数据库事务与锁

事务总结  事务是什么?    事务(Transaction)是并发控制的基本单位。所谓的事务,它是一个操做序列,这些操做要么都执行,要么都不执行,它是一个不可分割的工做单位。   例如,银行转帐工做:从一个帐号扣款并使另外一个帐号增款,这两个操做要么都执行,要么都不执行。因此,应该把它们当作一个事务.   事务是数据库维护数据一致性的单位,在每一个事务结束时,都能保持数据一致性。 事务都有哪些特征?    原子性:事务中包含的操做被看作一个逻辑单元,这个逻辑单元中的操做要么所有成功要么所有失败.    一致性:只有合法的数据能够写入数据库,不然事务应该将其回滚到最初状态.    隔离性: 事务容许多个用户对同一个数据进行并发访问,而不破坏数据的正确性和完整性. 同时,并行事务的修改必须与其余并行事务的修改相互独立.    持久性: 事务结束后,事务处理的结果必须可以获得固化  简单的说,事务是一种机制,用以维护数据库的完整性 事务的语句:  开始事务 Begin Transaction 提交事务 Commit Transaction 回滚事务 RollBack Transaction 数据库事务与锁 解锁用: ALTER system KILL session 'SID,serial#'; 排它锁/共享锁||悲观锁/乐观锁 1.共享锁只用于表级,排他锁用于行级。 2.加了共享锁的对象,能够继续加共享锁,不能再加排他锁。加了排他锁后,不能再加任何锁。 3.好比一个DML操做,就要对受影响的行加排他锁,这样就不容许再加别的锁,也就是说别的会话不能修改这些行。同时为了不在作这个DML操做的时候,有别的会话执行DDL,修改表的定义,因此要在表上加共享锁,这样就阻止了DDL的操做。 4.当执行DDL操做时,就须要在全表上加排他锁 为何须要锁(并发控制)? 在多用户环境中,在同一时间可能会有多个用户更新相同的记录,这会产生冲突。这就是著名的并发性问题。 典型的冲突有:   l 丢失更新:一个事务的更新覆盖了其它事务的更新结果,就是所谓的更新丢失。例如:用户A把值从6改成2,用户B把值从2改成6,则用户A丢失了他的更新。   l 脏读:当一个事务读取其它完成一半事务的记录时,就会发生脏读取。例如:用户A,B看到的值都是6,用户B把值改成2,用户A读到的值仍为6。 为了解决这些并发带来的问题。 咱们须要引入并发控制机制。 并发控制机制 悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操做。[1] 乐观锁:假设不会发生并发冲突,只在提交操做时检查是否违反数据完整性。[1] 乐观锁不能解决脏读的问题。 乐观锁应用   1. 使用自增加的整数表示数据版本号。更新时检查版本号是否一致,好比数据库中数据版本为6,更新提交时version=6+1,使用该version值(=7)与数据库version+1(=7)做比较,若是相等,则能够更新,若是不等则有可能其余程序已更新该记录,因此返回错误。         2. 使用时间戳来实现. 注:对于以上两种方式,Hibernate自带实现方式:在使用乐观锁的字段前加annotation: @Version, Hibernate在更新时自动校验该字段。   悲观锁应用   须要使用数据库的锁机制,好比SQL SERVER 的TABLOCKX(排它表锁) 此选项被选中时,SQL  Server  将在整个表上置排它锁直至该命令或事务结束。这将防止其余进程读取或修改表中的数据。 SqlServer中使用 Begin Tran select top 1 @TrainNo=T_NO from Train_ticket   with (UPDLOCK)   where S_Flag=0        update Train_ticket set T_Name=user,     T_Time=getdate(),     S_Flag=1 where T_NO=@TrainNo commit 咱们在查询的时候使用了with (UPDLOCK)选项,在查询记录的时候咱们就对记录加上了更新锁,表示咱们即将对此记录进行更新. 注意更新锁和共享锁是不冲突的,也就是其余用户还能够查询此表的内容,可是和更新锁和排它锁是冲突的.因此其余的更新用户就会阻塞. 结论 在实际生产环境里边,若是并发量不大且不容许脏读,可使用悲观锁解决并发问题;但若是系统的并发很是大的话,悲观锁定会带来很是大的性能问题,因此咱们就要选择乐观锁定的方法.