文章目录
一,实现声明式事务
1,添加spring-aspects-4.3.10.RELEASE.jar包
2,在Spring配置文件中添加如下配置:
<bean id="transaction" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" p:dataSource-ref="dataSource"></bean>
<tx:annotation-driven transaction-manager="transaction"/> //用于开启注解
3,在service层给需要开启事务的方法添加注解:@Transactional
二,@Transactional注解属性
readOnly
事务只读,当其属性值设置为true时对事务性资源进行只读操作。如果方法中有对数据进行修改的操作则会报错。
timeout
设置事务运行时长,如事务在这个时长内未完成,自动回滚事务且出现org.springframework.transaction.TransactionTimedOutException异常
rollbackFor和rollbackForClassName
指定对哪些异常回滚事务,两个属性作用一样。
默认情况下,在事务抛出运行时异常时回滚事务。
可以设置为在抛出检查时异常时回滚事务:
@Transactional(rollbackFor=Exception.class)
propagation
propagation用于指定事务传播行为,一个事务方法被另一个事务方法调用时,必须指定事务应该如何传播。
默认值为:REQUIRED
事务方法A被另一个事务方法 B调用时,事务方法A默认在B方法的事务内运行,即A方法和B方法在同一个事务中(相当于修饰S方法的@Transactional注解中添加了“propagation=Propagation.REQUIRED”属性)
当A方法被多次执行,若其中一次出现异常,则所有执行过的事务回滚
REQUIRES_NEW属性:
修饰A方法的@Transactional注解中添加了“propagation=Propagation.REQUIRES_NEW”属性,则每次执行该方法时都会启动新事务
当A方法被多次执行,若其中一次出现异常,则出现异常的这次事务回滚
注意:若A方法和B方法在同一个类中,REQUIRES_NEW属性无效
三,isolation:事务隔离级别
Spring定义了如下5种事务隔离级别:
DEFAULT:默认值,表示使用底层数据库的默认隔离级别。对大部分数据库而言,通常为READ_COMMITTED。
READ_UNCOMMITTED:表示一个事务可以读取另一个事务修改但还没有提交的数据。该级别可能出现脏读、不可重复读或幻读,因此很少使用该隔离级别。
READ_COMMITTED:表示一个事务只能读取另一个事务已经提交的数据。该级别可以防止脏读,但可能出现不可重复读或幻读,这也是大多数情况下的推荐值。
REPEATABLE_READ:表示一个事务在整个过程中可以多次重复执行某个查询,且每次返回的记录都相同,除非数据被当前事务自生修改。即使在多次查询之间有新增的数据满足该查询,这些新增的记录也会被忽略。该级别可以防止脏读和不可重复读,但可能出现幻读。
SERIALIZABLE:表示所有的事务依次逐个执行,事务之间互不干扰,该级别可以防止脏读、不可重复读和幻读,但是这将严重影响程序的性能,因此通常情况下也不会用到该级别。
说明:
1,Oracle 支持
READ_COMMITED
SERIALIZABLE
两种事务隔离级别,默认为READ_COMMITED;
2,MySQL 支持
READ_UNCOMMITTED
READ_COMMITTED
REPEATABLE_READ
SERIALIZABLE
四种事务隔离级别,默认为:REPEATABLE_READ。
四,事务并发
同一个应用程序中的多个事务或不同应用程序中的多个事务在同一个数据集上并发执行时, 可能会出现许多意外的问题,这些问题可分为如下三种类型:
脏读
即两个事务A和B,A执行了一个事务但未提交,B读到了A更改但未提交的数据即为脏读。
不可重复读
即有两个事务A和B,A 多次读取同一数据,B 在A多次读取的过程中对数据作了修改并提交,导致A多次读取同一数据后的结果不一致。
幻读
已知有两个事务A和B,A从一个表中读取了数据,然后B在该表中插入了一些新数据,导致A再次读取同一个表, 就会多出几行,简单地说,一个事务中先后读取一个范围的记录,但每次读取的纪录数不同,称之为幻象读
解决事务并发
通过设置数据库的事务隔离级别可以解决多个事务并发情况下出现的脏读、不可重复读和幻读问题,数据库事务隔离级别由低到高依次为Read uncommitted、Read committed、Repeatable read和Serializable等四种。(√表示可能出现,×表示不会出现)
注意:隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。
五,Mysql中的事务隔离级别
1,如何查看Mysql数据库的事务隔离级别?
执行 select @@global.tx_isolation,@@tx_isolation; 语句即可
Mysql数据库支持Read uncommitted、Read committed、Repeatable read和Serializable四种事务隔离级别,默认为Repeatable read
2,如何修改Mysql数据库的事务隔离级别?
(1)全局修改:在my.ini配置文件最后加上如下配置:
#可选参数有:READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE.
[mysqld]
transaction-isolation = READ-UNCOMMITTED
(2)局部修改:执行语句 set session transaction isolation level read uncommitted;
注意:修改完Mysql数据库的隔离级别后需要重启MySQL服务:
右击Mysql即有重启服务选项