事务详解
来源:互联网 发布:智能社node抽奖 编辑:程序博客网 时间:2024/06/06 23:16
一、事务的ACID属性
事务使用ACID特性来衡量事务的质量。
1、原子性
事务必须是原子的,在事务结束的时候,事务中的所有任务必须全部成功完成,否则全部失败,事务回滚到事务开始之间的状态。
2、一致性
事务必须保证和数据库的一致性,即数据库中的所有数据和现实保持一致。如果事务失败数据必须返回到事务执行之前的状态,反之修改数据和现实的同步。
3、隔离性
隔离性是事务与事务之间的屏障,每个事务必须与其他事务的执行结果隔离开,直到该事务执行完毕,它保证了事务的访问的任何数据不会受其他事务执行结果的影响。
4、持久性
如果事务成功执行,无论系统发生任何情况,事务的持久性都必须保证事务的执行结果是永久的。
二、事务的隔离级别
ANSI/ISO SQL标准定义了4中事务隔离级别:
1、读未提交(read uncommitted)
一个事务读取另外一个尚未提交的事务的数据。
2、读已提交(read committed)
一个事务读取另外已经提交的事务的数据。
3、重复读(repeatable read)
一个事务在两个不同时间点读取的数据是一致的。
4、串行读(serializable read)
不同的事务是按顺序执行,不会相互影响。
对于不同的事务,采用不同的隔离级别分别有不同的结果,不同的隔离级别有不同的现象,主要有下面3种现象:
(1) 脏读(dirty read)
一个事务可以读取另一个尚未提交事务的修改数据。
‘读未提交’这种事务隔离级别则可能会出现脏读的情况。
(2) 非重复读(nonrepeatable read)
在同一个事务中,同一个查询在T1时间读取某一行,在T2时间重新读取这一行时候,这一行的数据已经发生修改,可能被更新了(update),也可能被删除了(delete)。
(3) 幻像读(phantom read)
在同一事务中,同一查询多次进行时候,由于其他插入操作(insert)的事务提交,导致每次返回不同的结果集。
不同的隔离级别有不同的现象,并有不同的锁定/并发机制,隔离级别越高,数据库的并发性就越差,4种事务隔离级别分别表现的现象如下:
(1) 读未提交(read uncommitted)
允许出现脏读、不可重复读、幻象读。
(2) 读已提交(read committed)
不会出现脏读,允许出现不可重复读、幻象读。
(3) 重复读(repeatable read)
不会出现脏读、不可重复读,允许出现幻象读。
(4) 串行读(serializable read)
不会出现脏读、不可重复读、幻象读。
常用数据库的事务隔离级别
(1) MySQL
默认的隔离级别是:repeatable read
(2) ORACLE
默认的隔离级别是:read committed
三、MYSQL中的事务
在MySQL中默认事务隔离级别是可重复读(Repeatable read).可通过SQL语句查询:
查看InnoDB系统级别的事务隔离级别:
mysql> SELECT @@global.tx_isolation;+-----------------------+| @@global.tx_isolation |+-----------------------+| REPEATABLE-READ |+-----------------------+
查看InnoDB全局级别的事务隔离级别
查看InnoDB会话级别的事务隔离级别:mysql> SELECT @@tx_isolation;+-----------------+| @@tx_isolation |+-----------------+| REPEATABLE-READ |+-----------------+
MYSQL中事务隔离级别的值有:
READ COMMITTED
READ UNCOMMITTED
REPEATABLE READ
SERIALIZABLE
1、修改事务隔离级别是read uncommitted
事务T1在执行的过程中会去读取事务T2中未提交的数据,从而出现脏读。
2、修改事务隔离级别是read committed
出现不可重复读问题。
3、修改事务隔离级别是read repeatable
不会出现不可重复读的问题,但会出现幻读。
4、修改事务隔离级别是read serializable
如果事务的隔离级别是read serializable,意味着事务是排队执行的,事务之间不会相互影响,这种情况下不会出现脏读、不可重复读和幻读的情况,但数据库的并发性能非常差,所以一般数据库都不会使用这种隔离级别。
四、Spring的事务管理方式
(1)编程式事务
在代码中实现事务的控制,比较少用。
(2)声明式事务
通过配置AOP的方式来实现事务的控制,比较简洁。
定义事务管理器
<beanid="txManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<propertyname="dataSource"ref="dataSource"></property>
</bean>
定义通知
<tx:adviceid="txAdvice"transaction-manager="txManager">
<tx:attributes>
<tx:methodname="get*"/>
<tx:methodname="query*"/>
<tx:methodname="search*"/>
<tx:methodname="save*"propagation="REQUIRED"/>
<tx:methodname="update*"propagation="REQUIRED"/>
<tx:methodname="delete*"propagation="REQUIRED"/>
<tx:methodname="test*"propagation="REQUIRED"rollback-for="java.lang.Exception"/>
<tx:methodname="*"read-only="true"/>
</tx:attributes>
</tx:advice>
<!--
propagation传播属性的值
REQUIRED:默认值,业务方法需要在一个事务中运行。如果方法运行时,已经在一个事务中,那么加入到该事务,否则自己创建一个新的事务。一般spring默认都是这种事务,像保存,删除,修改等都是这种事务。
SUPPORTS:如果方法在某个事务范围内被调用,则方法成为该事务的一部分。如果业务方法在事务范围外被调用,则方法在没有事务的环境下执行。
MANDATORY:该属性指定业务方法必须在一个事务中运行,业务方法不能发起自己的事务。如果业务方法在没有事务的环境下调用,容器会抛出例外。
REQUIRES_NEW:属性不管是否存在事务,业务方法总会为自己发起一个新的事务。如果方法已经运行在一个事务中,则原有事务被挂起,新的事务会被创建,直到方法执行结束,新事务才算结束,原先事务才会恢复执行。
NOT_SUPPORTED:声明方法不需要事务。如果方法没有关联到一个事务,容器不会为它开启事务。如果方法在一个事务中被调用,该事务会被挂起,在方法调用结束后,原先的事务便会执行。
NEVER:指定业务方法绝对不能在事务范围内执行。如果业务方法在某个事务中执行,容器会抛出例外,只有业务方法没有关联到任何事务,才能正常执行。
NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中,如果没有活动事务,则按Required属性执行,它使用了一个单独的事务,这个事务拥有多个可以回滚的保存点。内部事务的回滚不会对外部事务造成影响,它只对DataSourceTransactionManager事务管理器起效。
-->
<!--
isolation隔离属性的值
DEFAULT:默认值,使用数据库默认的隔离级别
READ_COMMITTED:Oracle中默认的事务隔离级别,允许读取其他并发事务已经提交的更新(防止脏读)
READ_UNCOMMITTED:允许读取其他并发事务还未提交的更新,会导致事务之间的3个缺陷发生,这是速度最快的一个隔离级别,但同时它的隔离级别也是最低
REPEATABLE_READ:MySQL5默认的事务隔离级别,除非事务自身修改了数据,否则规定事务多次重复读取,数据必须相同(防此脏读,不可重复读)
SERIALIZABLE:这是最高的隔离级别,它可以防此脏读,不可重复读和幻读等问题,但因其侵占式的数据记录完全锁定,导致它影响事务的性能,成为隔离级别中最展慢的一个。
-->
<!--
timeout超时属性,默认值-1,以秒为单位
-->
<!--
read-only只读属性,默认值false,为true的话,事务只能读数据,而不能进行了插入、修改、删除操作。而且默认将数据库的隔离级别提高一级到可重复读。
可重复读:从这一点设置的时间点开始(时间点a)到这个事务结束的过程中,其他事务所提交的数据,该事务将看不见!(查询中不会出现别人在时间点a之后提交的数据)
-->
<!--
rollback-for, service中触发回滚的异常。
spring默认只在发生未被捕获的RuntimeException时才回滚
如果配置rollback-for="java.lang.Exception",那么service中抛出异常java.lang.Exception时,事务就会回滚。
-->
配置切入点
<aop:config>
<aop:pointcutid="servicePointcut"expression="execution(* com.service..*.*(..))"/>
<aop:advisoradvice-ref="txAdvice"pointcut-ref="servicePointcut"/>
</aop:config>
<!--
execution(* com.service..*.*(..))的解读
第一个*号表示任务返回类型
com.service.* 表示包com.service下的任意类
com.service..* 表示包com.service及其子包下的任意类
com.service.*.* 表示包com.service下的任意类的任意方法
com.service..*.* 表示包com.service及其子包下的任意类的任意方法
(..) 匹配0个参数或者多个参数的,任意类型
(x,..) 第一个参数的类型必须是X
(x,,,s,..) 匹配至少4个参数,第一个参数必须是x类型,第二个和第三个参数可以任意,第四个必须是s类型。
-->
- 事务详解
- 事务详解
- 事务详解
- 事务详解
- 事务详解
- 事务详解
- 事务详解
- 事务详解
- 事务详解
- Spring详解-----------事务详解
- Spring详解-----------事务详解
- 【词汇详解】事务详解
- EJB组件事务详解
- 详解spring事务属性
- 详解spring事务属性
- 详解spring事务属性
- 详解spring事务属性
- 详解spring事务属性
- jar包中的MANIFEST.MF文件解析
- 深圳 上海 北京 南京 武汉
- asp.net中的窗体身份验证(不同的角色访问不同的目录)
- 《生化危机5:惩罚》观后感
- the enhancement of OnlineJudge and phpwiki
- 事务详解
- 金蝶 k3 打开帐套时提示 中间层配置有误 .
- GVim 配置说明
- RecordsetPtr指针
- WinCE6下的kernelIoControl使用方法
- 女性皮肤保养
- 正式开始学习C#-----V0.2
- Centos能上内网不能上外网
- InstallShield 12 制作安装包