Preface
The download address of the sample code for this article (completely run, including SQL files, please modify the database configuration after downloading): Click here to download
Several database operations are controlled as a whole, and they succeed or fail together.
Atomicity: refers to a transaction being an inseparable unit of work, and operations in a transaction either occur or none occur.
Consistency: means that the integrity of data before and after a transaction must be consistent.
Isolation: When multiple users access the database concurrently, one user's transactions cannot be interfered by the transactions of other users, and the data between multiple concurrent transactions must be isolated from each other.
Persistence: Once a transaction is committed, its changes to the data in the database are permanent, and the failure of the instant database should not have any impact on it.
--Platform TransactionManager Transaction Manager (commit, rollback transactions)
Spring provides different Platform TransactionManager interface implementations for different persistence frameworks. like:
Using DataSourceTransactionManager when persisting data using Spring JDBC or iBatis
Use HibernateTransactionManager when using Hibernate3.0 for persistent data
--TransactionDefinition Transaction definition information (isolation, propagation, timeout, read-only)
Dirty Reading: One transaction reads data that has been rewritten by another transaction but has not yet been submitted. If this data is rolled back, the read data is invalid.
No repetitive reading: In the same transaction, the results returned by reading the same data multiple times are different.
Fantasy reading: After one transaction reads several lines of records, another transaction inserts some records, and fantasy reading occurs. In the later query, the first transaction will find some records that were not originally available.
Transaction isolation level: (five types)
Among them, MySQL uses the REPEATABLE_READ isolation level by default; Oracle uses the READ_COMMITTED isolation level by default
Transaction communication behavior: (seven types)
--TransactionStatus Transaction specific operation status
a. Programming transaction management (based on Java programming control, rarely used)--see demo1 package
Use TransactionTemplate to encapsulate multiple DAO operations
*b. Declarative transaction management (Spring-based AOP configuration control)
- Based on TransactionProxyFactoryBean. (Seldom used)--see demo2 package
It is necessary to configure a TransactionProxyFactoryBean for each class that is undergoing transaction management for enhancement.
-Based on XML configuration (used frequently)-see demo3 package
Once configured, nothing needs to be added to the class.
If Action is a target object to enter the transaction, you need to add the proxy-target-class="true" attribute to the <aop:config> element. The reason is to inform the Spring framework to use CGLIB technology to generate Action classes with transaction management functions.
-Based on annotations (simple configuration, often used)-see demo4 package
Enable transaction annotation configuration in applicationContext.xml. (In applicationContext.xml, just define the bean and append the following elements)
<bean id="txManager"> <property name="sessionFactory"> </property><tx:annotation-driven transaction-manager="txManager"/>
Use @Transactional in the target component class, which can be defined before the class or before the method.
--Programming
/** * @Description: DAO layer interface of transfer case* */ public interface AccountDao { /** * @param out * :Transfer account* @param money * :Transfer amount*/ public void outMoney(String out, Double money); /** * * @param in * :Transfer account* @param money * :Transfer amount*/ public void inMoney(String in, Double money); } /** * @Description: The DAO layer implementation class of the transfer case*/ public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao { /** * @param out * :Transfer account* @param money * :Transfer amount*/ @Override public void outMoney(String out, Double money) { String sql = "update account set money = money-? where name = ?"; this.getJdbcTemplate().update(sql, money, out); } /** * @param in * :Transfer account* @param money * :Transfer amount*/ @Override public void inMoney(String in, Double money) { String sql = "update account set money = money+? where name = ?"; this.getJdbcTemplate().update(sql, money, in); } } /** * @Description: Business interface of transfer case* */ public interface AccountService { /** * @param out : Transfer out * @param in : Transfer account* @param money : Transfer amount*/ public void transfer(String out,String in,Double money); } /** * @Description: Business layer implementation class of the transfer case*/ public class AccountServiceImpl implements AccountService { // DAO private AccountDao accountDao; // Template for injecting transaction management private TransactionTemplate transactionTemplate; /** * @param out * :Transfer out * @param in * :Transfer account* @param money * :Transfer amount*/ @Override public void transfer(final String out, final String in, final Double money) { // If an exception occurs during the process, the previous operation can be completed. If the latter cannot, the transfer is successful but the transfer is not received. // accountDao.outMoney(out, money); // int i = 1/0; // accountDao.inMoney(in, money); transactionTemplate.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult( TransactionStatus transactionStatus) { accountDao.outMoney(out, money); // int i = 1 / 0;//Transaction control, that is, an exception occurs, and the code in this segment is executed invalid accountDao.inMoney(in, money); } }); } public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; } public void setTransactionTemplate(TransactionTemplate transactionTemplate) { this.transactionTemplate = transactionTemplate; } }applicationContext1.xml
<!-- Introduce external property files--> <context:property-placeholder location="classpath:jdbc.properties"/> <!-- Configure c3p0 connection pool--> <bean id="dataSource"> <property name="driverClass" value="${jdbc.driverClass}" /> <property name="jdbcUrl" value="${jdbc.url}" /> <property name="user" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean> <!-- Configure the business layer class --> <bean id="accountService"> <property name="accountDao" ref="accountDao" /> <!-- Inject the template for transaction management --> <property name="transactionTemplate" ref="transactionTemplate" /> </bean> <!-- Configure the DAO class (simplified, JdbcTemplate will be automatically configured) --> <bean id="accountDao"> <property name="dataSource" ref="dataSource" /> </bean> <!-- Configure the DAO class (not simplified) --> <!-- <bean id="jdbcTemplate"> <property name="dataSource" ref="dataSource" /> </bean> <bean id="accountDao"> <property name="jdbcTemplate" ref="jdbcTemplate" /> </bean> --> <!-- =============================================================================================================================================================================================================================================================================================================================================================================================================================================================== Configure transaction management template: Classes provided by Spring to simplify transaction management code --> <bean id="transactionTemplate"> <property name="transactionManager" ref="transactionManager"/> </bean>test:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext1.xml") public class TransactionTest { @Resource(name = "accountService") private AccountService accountService; @Test public void demo1() { accountService.transfer("aaa", "bbb", 200d); } }--A method based on TransactionProxyFactoryBean
public class AccountServiceImpl implements AccountService { // DAO private AccountDao accountDao; /** * @param out * :Transfer out * @param in * :Transfer account* @param money * :Transfer amount*/ @Override public void transfer(String out, String in, Double money) { accountDao.outMoney(out, money); // int i = 1/0; accountDao.inMoney(in, money); } public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; } }applicationContext2.xml
<!-- Introduce external property files--> <context:property-placeholder location="classpath:jdbc.properties"/> <!-- Configure c3p0 connection pool--> <bean id="dataSource"> <property name="driverClass" value="${jdbc.driverClass}" /> <property name="jdbcUrl" value="${jdbc.url}" /> <property name="user" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean> <!-- Configure the business layer class --> <bean id="accountService"> <property name="accountDao" ref="accountDao" /> </bean> <!-- Configure the DAO class (simplified, automatically configure JdbcTemplate) --> <bean id="accountDao"> <property name="dataSource" ref="dataSource" /> </bean> <!-- ====================================================================================================================================================================================================================================================================================================================================================================================================== --> <!-- Configure transaction manager --> <bean id="transactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <!-- Configure the proxy for the business layer --> <bean id="accountServiceProxy"> <!-- Configure the target object --> <property name="target" ref="accountService" /> <!-- Inject transaction manager --> <property name="transactionManager" ref="transactionManager"></property> <!-- Inject transaction properties --> <property name="transactionAttributes"> <props> <!-- Format of prop: * PROPAGATION: Transaction propagation behavior* ISOTATION: Transaction isolation level* readOnly: Read-only* -EXCEPTION: Which exceptions roll back transactions* +EXCEPTION: Which exceptions do not roll back transactions--> <prop key="transfer">PROPAGATION_REQUIRED</prop> <!-- <prop key="transfer">PROPAGATION_REQUIRED,readOnly</prop> --> <!-- <prop key="transfer">PROPAGATION_REQUIRED,readOnly</prop> --> <!-- <prop key="transfer">PROPAGATION_REQUIRED,+java.lang.ArithmeticException</prop> --> </props> </property> </bean>test:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext2.xml") public class TransactionTest { /** * Be sure to inject the proxy class: because the proxy class performs enhanced operations*/ // @Resource(name="accountService") @Resource(name = "accountServiceProxy") private AccountService accountService; @Test public void demo1() { accountService.transfer("aaa", "bbb", 200d); } }--Based on XML configuration
public class AccountServiceImpl implements AccountService { // DAO private AccountDao accountDao; /** * @param out * :Transfer out * @param in * :Transfer account* @param money * :Transfer amount*/ @Override public void transfer(String out, String in, Double money) { accountDao.outMoney(out, money); // int i = 1/0; accountDao.inMoney(in, money); } public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; } }applicationContext3.xml
<!-- Introduce external property files--> <context:property-placeholder location="classpath:jdbc.properties"/> <!-- Configure c3p0 connection pool--> <bean id="dataSource"> <property name="driverClass" value="${jdbc.driverClass}" /> <property name="jdbcUrl" value="${jdbc.url}" /> <property name="user" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean> <!-- Configure the business layer class --> <bean id="accountService"> <property name="accountDao" ref="accountDao" /> </bean> <!-- Configure the DAO class (simplified, automatically configure JdbcTemplate) --> <bean id="accountDao"> <property name="dataSource" ref="dataSource" /> </bean> <!-- =============================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================== : Transaction propagation behavior isolation : Transaction isolation level read-only : Read-only rollback-for: Which exceptions have occurred no-rollback-for: Which exceptions have occurred not rollback timeout : Expiration information --> <tx:method name="transfer" propagation="REQUIRED"/> </tx:attributes> </tx:advice> <!-- Configuration section--> <aop:config> <!-- Configuration point--> <aop:pointcut expression="execution(* com.zs.spring.demo3.AccountService+.*(..))" id="pointcut1"/> <!-- Configuration section--> <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1"/> </aop:config>test:
/** * @Description: Spring's declarative transaction management method two: AspectJ-based XML configuration*/ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext3.xml") public class TransactionTest { /** * Must inject the proxy class: because the proxy class performs enhanced operations*/ @Resource(name = "accountService") private AccountService accountService; @Test public void demo1() { accountService.transfer("aaa", "bbb", 200d); } }--Based on annotation
/** * @Transactional Propagation: Transaction propagation behavior isolation: Transaction isolation level readOnly: Read-only* rollbackFor: Which exceptions have occurred noRollbackFor: Which exceptions have occurred not rollback* rollbackForClassName Rollback according to the exception class name*/ @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, readOnly = false) public class AccountServiceImpl implements AccountService { // DAO injecting transfer private AccountDao accountDao; /** * @param out * :Transfer account* @param in * :Transfer account* @param money * :Transfer amount*/ @Override public void transfer(String out, String in, Double money) { accountDao.outMoney(out, money); // int i = 1/0; accountDao.inMoney(in, money); } public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; } }applicationContext4.xml
<!-- Introduce external property files--> <context:property-placeholder location="classpath:jdbc.properties"/> <!-- Configure c3p0 connection pool--> <bean id="dataSource"> <property name="driverClass" value="${jdbc.driverClass}" /> <property name="jdbcUrl" value="${jdbc.url}" /> <property name="user" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean> <!-- Configure the business layer class --> <bean id="accountService"> <property name="accountDao" ref="accountDao" /> </bean> <!-- Configure the DAO class (simplified, automatically configure JdbcTemplate) --> <bean id="accountDao"> <property name="dataSource" ref="dataSource" /> </bean> <!-- ====================================================================================================================================================================================================================================================================================================================================================================================================== Configure transaction manager --> <bean id="transactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <!-- Turn on annotation transaction--> <tx:annotation-driven transaction-manager="transactionManager"/>test:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext4.xml") public class TransactionTest { /** * Be sure to inject the proxy class: because the proxy class performs enhanced operations*/ @Resource(name = "accountService") private AccountService accountService; @Test public void demo1() { accountService.transfer("aaa", "bbb", 200d); } }For specific code and database file reference project complete code:
http://xiazai.VeVB.COM/201805/yuanma/Spring-transaction_jb51.rar
Summarize
The above is the entire content of this article. I hope that the content of this article has certain reference value for everyone's study or work. If you have any questions, you can leave a message to communicate. Thank you for your support to Wulin.com.