事务&锁&spring支持

1.数据库事务


1.0 事务特性(ACID)

Atomicity:原子性,一个事务不可以被拆分

Consistency:一致性,

Isolation:隔离性,多个事务操作数据,不能相互影响

Durability:持久性


1.1 事务隔离级别

在SQL92标准中,事务隔离级别分为四种,分别为:

隔离级别(低->高)
脏读 不可重复读 幻读 第一类更新丢失 第二类更新丢失 数据库默认级别
read uncommitted 读取未提交的内容 y y y y y
read committed 读已提交 x y y x y oracle\sql server
repeatable read
可重复读 x x y
x x mysql
serializable
可串行化 x x x x x


其中Read Uncommitted与Read Committed为语句级别的, 而Read Repeatable与Serializable是针对事务级别的。 

事务&锁&spring支持_第1张图片

1.1.1 mysql-InnoDB引擎默认事务隔离级别repeatable-read  

1.1.2 sqlServer,Oracle默认事务隔离级别read commited 

1.1.2 查询与设置事务隔离级别

1.1.2.1 mysql

#mysql版本
select version(); 
#存储引擎的事务隔离级别
select @@global.tx_isolation,@@tx_isolation;
#设置会话事务隔离级别
set session tx_isolation='serializable'; 
#设置全局的事务隔离级别
set global tx_isolation='serializable';
set session transaction isolation level read committed;

1.1.2.2 sql Server


1.2事务并发引起的问题

1.2.1脏读:数据已修改事务没提交,另一事务读取到未提交的数据!(事务没提交另一事务就读到未提交的数据)

事务&锁&spring支持_第2张图片

1.2.2不可重复读:同一事务两次读取数据不一样;第一个事务读去数据,第二个事务修改数据提交,第一个事务再一次读取数据,这样第一个事务两次读取的数据将不一致。

事务&锁&spring支持_第3张图片

1.2.3幻读:两个事务,第一个事务将所有行的数据都修改了,第二个事务将插入一条数据提交,第1个事务提交发现有一条数据并没有修改。

事务&锁&spring支持_第4张图片

1.2.4第一类丢失(回滚丢失)

事务&锁&spring支持_第5张图片

当2个事务更新相同的数据源,如果第一个事务被提交,而另外一个事务却被撤销,那么会连同第一个事务所做的跟新也被撤销。也就是说第一个事务做的跟新丢失了

1.2.5第二类更新丢失(覆盖丢失)

事务&锁&spring支持_第6张图片

加深理解:

  1. 不可重复读和幻读的区别

两者都是相同事务两次读取不一致,一个是被另外事务修改读取不一致,一个是被另外事务插入读取不一致。

          不可重复读,针对表内的修改,只需要锁住满足条件的记录,加锁的方式不同
           幻读,针对表内的插入,要锁住满足条件及其相近的记录


2.数据库锁(Lock granularity)

2.1 数据库锁

2.1.a 引用文章

http://www.cnblogs.com/zhouqianhua/archive/2011/04/15/2017049.html

2.1.1读锁(共享锁):

2.1.2更新锁:

2.1.3写锁(排他锁):

2.1.4意向锁:

2.1.5计划锁:

2.2 数据库锁粒度

表锁:管理锁的开销最小,同时允许的并发量也最小的锁机制。MyIsam存储引擎使用的锁机制。当要写入数据时,把整个表都锁上,此时其他读、写动作一律等待。在MySql中,除了MyIsam存储引擎使用这种锁策略外,MySql本身也使用表锁来执行某些特定动作,比如alter table.

行锁:可以支持最大并发的锁策略。InnoDB和Falcon两张存储引擎都采用这种策略。

注意:

SELECT ... FOR UPDATE ,不过锁定(Lock)的数据是判别就得要注意一下了。由于InnoDB 预设是Row-Level Lock,所以只有查询条件要指定索引并预防索引失效,MySQL 才会执行Row lock (只锁住被选取的数据) ,否则MySQL 将会执行Table Lock (将整个数据表单给锁住)


LOCK TABLE和UNLOCK TABLE 表锁


3.spring事务

引用文章:http://blog.csdn.net/it_man/article/details/5074371

3.1 事务传播行为(Transaction Propagation Behavior)

事务在方法中传播。

  1. PROPAGATION_REQUIRED

  2. RROPAGATION_REQUIRES_NEW

  3. PROPAGATION_NESTED

  4. PROPAGATION_SUPPORTS

  5. PROPAGATION_NOT_SUPPORTED

  6. PROPAGATION_NEVER

  7. PROPAGATION_MANDATORY

    首先要明确的是,事务是从哪里来?传播到哪里去?答案是,从方法 A 传播到方法 B。Spring 解决的只是方法之间的事务传播,那情况就多了,比如:

  1. 方法 A 有事务,方法 B 也有事务。

  2. 方法 A 有事务,方法 B 没有事务。

  3. 方法 A 没有事务,方法 B 有事务。

  4. 方法 A 没有事务,方法 B 也没有事务。 

假设事务从方法 A 传播到方法 B,您需要面对方法 B,问自己一个问题:

方法 A 有事务吗?

  1. 如果没有,就新建一个事务;如果有,就加入当前事务。这就是 PROPAGATION_REQUIRED,它也是 Spring 提供的默认事务传播行为,适合绝大多数情况。

  2. 如果没有,就新建一个事务;如果有,就将当前事务挂起。这就是 RROPAGATION_REQUIRES_NEW,意思就是创建了一个新事务,它和原来的事务没有任何关系了。

  3. 如果没有,就新建一个事务;如果有,就在当前事务中嵌套其他事务。这就是 PROPAGATION_NESTED,也就是传说中的“嵌套事务”了,所嵌套的子事务与主事务之间是有关联的(当主事务提交或回滚,子事务也会提交或回滚)。

  4. 如果没有,就以非事务方式执行;如果有,就使用当前事务。这就是 PROPAGATION_SUPPORTS,这种方式非常随意,没有就没有,有就有,有点无所谓的态度,反正我是支持你的。

  5. 如果没有,就非事务方式执行;如果有,就将当前事务挂起。这就是 PROPAGATION_NOT_SUPPORTED,这种方式非常强硬,没有就没有,有我也不支持你,把你挂起来,不鸟你。

  6. 如果没有,就非事务方式执行;如果有,就抛出异常。这就是 PROPAGATION_NEVER,这种方式更猛,没有就没有,有了反而报错,确实够牛的,它说:我从不支持事务!

  7. 如果没有,就抛出异常;如果有,就使用当前事务。这就是 PROPAGATION_MANDATORY,这种方式可以说是牛逼中的牛逼了,没有事务直接就报错,确实够狠的,它说:我必须要有事务!

3.2 spring 事务管理的方式

声明式事务:TransactionProxyFactoryBean 在spring 配置文件中进行配置或者使用注解

编程式事务:TransactionTemplate PlatformTransactionManager



4.hibernate事务

8 - Serializable 串行化
4 - Repeatable Read 可重复读
2 - Read Commited 可读已提交
1 - Read Uncommited 可读未提交

在hibernate.cfg.xml中使用hibernate.connection.isolation参数配置数据库事务隔离级别

悲观锁

乐观锁



5.引用的文章

http://www.cnblogs.com/otomedaybreak/archive/2012/01/27/2330008.html#C4

http://www.iteye.com/topic/332577

http://my.oschina.net/huangyong/blog/160012?p=4#comments

你可能感兴趣的:(事务&锁&spring支持)