1.什么是事务(transaction)?
一组业务整体处理的行为叫做一个事务。
简单的说就是,在同一个事务管理的方法中,所有操作要不一起成功,要不一起失败。
2.事务的特性
a.事务通常被定义为一个不可分割的工作单元
b.事务控制多个应用程序对数据库的并发访问操作,确保数据的完整性。
c.在系统失效的情况下,事务确保恢复后,数据仍处于一致的状态。
3.事务相关的概念
事务API(Java Transaction API):简称JTA;
Java事务服务(Java Transaction Service):简称JTS;
JTA事务比JDBC事务更强大。一个JTA事务可以有多个参与者,而一个JDBC事务则被限定在一个单一的数据库连接。
4.数据库访问可能碰到的问题:
a、Lost update - 两个transactions同时更新同一行,由于第2个transaction的abort,造成2个更新都失去。这一般发生在系统没有对transaction进行隔绝。(事务隔离)
b、Dirty read - 一个transaction正在读取另一个还没有commited的transaction对数据库做的改变。如果第2个transaction roll back,那么第一个transaction读取的信息就是不同步的。(脏读)
c、Unrepeatable read - 一个transaction对数据库中同一行数据读取了2遍,但是读取出来的数据却不同。这可能发生的情况是在这两次读取的间隔另一个transaction对该行做了更新。(被更新)
d、Second lost updates problem - 这种问题是Unrepeatable read的一种特例。当2个transactions同时读取一行,其中一个对该行做了更新并且commited,此时另外一transaction可能也会对此行做更新。那么第一个transaction做的改变就失效了。(同时更新)
e、Phantom read - 一个transaction执行了2次同一个query,但是第2次query读出的结果集合有第一个不存在的行。这发生在在两次query执行之间另一个transaction新增了新行。(被插入了数据)
5.ORACLE的隔离级别
ORACLE提供了SQL92标准中的read committed和serializable,同时提供了非SQL92标准的read-only。
(1)read committed:
这是ORACLE缺省的事务隔离级别。
事务中的每一条语句都遵从语句级的读一致性。
保证不会脏读;但可能出现非重复读和幻像。
(2)serializable:
简单地说,serializable就是使事务看起来象是一个接着一个地顺序地执行。
仅仅能看见在本事务开始前由其它事务提交的更改和在本事务中所做的更改。
保证不会出现非重复读和幻像。
Serializable隔离级别提供了read-only事务所提供的读一致性(事务级的读一致性),同时又允许DML操作。
只要在serializable事务开始到结束之间有其他事务对serializable事务要修改的东西进行了修改并提交了修改,则发生无法序列化访问的错误。
(3)read-only:
遵从事务级的读一致性,仅仅能看见在本事务开始前由其它事务提交的更改。
不允许在本事务中进行DML操作。
read only是serializable的子集。它们都避免了非重复读和幻像。区别是在read only中是只读;而在serializable中可以进行DML操作。
read committed和serializable的区别和联系:
A、事务1先于事务2开始,并保持未提交状态。事务2想要修改正被事务1修改的行。事务2等待。如果事务1回滚,则事务2(不论是read committed还是serializable方式)进行它想要做的修改。如果事务1提交,则当事务2是read committed方式时,进行它想要做的修改;当事务2是serializable方式时,失败并报错“Cannot serialize access”,因为事务2看不见事务1提交的修改,且事务2想在事务1修改的基础上再做修改。
B、read committed和serializable可以在ORACLE并行服务器中使用。
6.设置隔离级别
设置一个事务的隔离级别
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SET TRANSACTION READ ONLY;
设置增个会话的隔离级别
ALTER SESSION SET ISOLATION_LEVEL SERIALIZABLE;
ALTER SESSION SET ISOLATION_LEVEL READ COMMITTED;
7.事务的应用场景
当同一事务中的某一操作发生了异常时,那么该事物的所有操作都将回滚。
当同一事务中某一操作发生了异常但又做了异常捕获try...catch处理,那么事务不会回滚。
事务管理通常用在service层,因为service层包含多个操作,能确保数据同步。
Spring默认只会滚RuntimeException,对抛出的Exception不回滚。
8.事务传播特性
(1)PROPAGATION_REQUIRED: 如果存在一个事务,则支持当前事务。如果没有事务则开启。
(2)PROPAGATION_SUPPORTS: 如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行。
(3)PROPAGATION_MANDATORY: 如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。
(4)PROPAGATION_REQUIRES_NEW: 总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。
(5)PROPAGATION_NOT_SUPPORTED: 总是非事务地执行,并挂起任何存在的事务。
(6)PROPAGATION_NEVER: 总是非事务地执行,如果存在一个活动事务,则抛出异常。
(7)PROPAGATION_NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务, 则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行
9.Spring事务的隔离级别
(1)ISOLATION_DEFAULT:这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.
(另外四个与JDBC的隔离级别相对应)
(2)ISOLATION_READ_UNCOMMITTED: 这是事务最低的隔离级别,它充许令外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读。
(3)ISOLATION_READ_COMMITTED: 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据
(4)ISOLATION_REPEATABLE_READ: 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免不可重复读情况产生。
(5)ISOLATION_SERIALIZABLE 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。