[Spring transaction], the reason why the service implements non-transactional methods in the class of direct calling of its own transaction method causes the transaction to be invalid, transaction is not

Source: Internet
Author: User

[Spring transaction], the reason why the service implements non-transactional methods in the class of direct calling of its own transaction method causes the transaction to be invalid, transaction is not

First, prepare the service interface.

public interface AccountService {    public void createAccount(Account account, int throwExpFlag) throws Exception;    public void createAccountShell(Account account, int i) throws Exception;}
public interface RoleService {        public void createAccountShell(Account account, int i) throws Exception;}

 

Related impl

@Servicepublic class AccountServiceImpl implements AccountService {    @Resource    private AccountDAO accountDAO;        @Override    @Transactional    public void createAccount(Account account, int throwExpFlag) throws Exception {        accountDAO.save(account);        RoleServiceImpl.throwExp(throwExpFlag);    }    @Override    public void createAccountShell(Account account, int i) throws Exception {        this.createAccount(account, i);    }}
@Servicepublic class RoleServiceImpl implements RoleService {    @Autowired    AccountService accountService;        public static void throwExp(int throwExpFlag) throws Exception {        if (throwExpFlag == 0) {            throw new RuntimeException("<< rollback transaction >>");        } else if (throwExpFlag != 1) {            throw new Exception("<< do not rollback transaction >>");        }    }    @Override    public void createAccountShell(Account account, int i) throws Exception {        accountService.createAccount(account, i);            }}

 

Test class

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration({"classpath:spring/spring-dao.xml", "classpath:spring/spring-service.xml"})public class ServiceTransactionTest extends TestCase {        public static Account account;        static {                account = new Account();        account.setId(779);        account.setUsername("779 USER");        account.setPassword("0123456");        }    @Autowired    AccountService accountService;        @Autowired    RoleService roleService;        @Test    public void test_1() throws Exception {        this.accountService.createAccount(account, 0);    }        @Test    public void test_2() throws Exception {        this.accountService.createAccountShell(account, 0);    }        @Test    public void test_3() throws Exception {        roleService.createAccountShell(account, 0);    }}

(1) When testing the test_1 method of the test class, spring normally takes over the transaction because the AccountServiceImpl. createAccount method shows that the transaction is configured (@ Transactional.

 

(2) When testing the test_2 method of the test class, the AccountServiceImpl. createAccountShell method does not display the configuration transaction, but it calls the AccountServiceImpl. createAccount method (configured transaction ). When RuntimeException is thrown, there is no rollback, indicating that spring has not taken over the transaction. (Cause: AccountServiceImpl. spring knows when createAccountShell is displayed for calling, but because AccountServiceImpl. createAccountShell does not display the configuration transaction, and spring does not manage the transaction. In AccountServiceImpl. although the createAccount Method for transaction configuration is called in createAccountShell, spring does not know or cannot determine the transaction context, so the result is not rollback due to the thrown runtime exception ).

 

(3) test test_3. Although RoleServiceImpl. createAccountShell does not configure transactions, spring takes over the transactions and rollback when RuntimeException is thrown. (Cause of speculation: Although RoleServiceImpl. createAccountShell does not configure transactions, but it internally calls the method of another service instance, that is, AccountService. spring knows this when creating an account, and because AccountServiceImpl. createAccount indicates that the transaction is configured, so spring takes over the transaction ).

 

(4) If a transaction is configured in AccountServiceImpl. createAccountShell, spring can take over the transaction when executing test_2.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.