1、事务的概念
事务是访问数据库的一个操作序列,数据库应用系统通过事务集来完成对数据的存取。事物的正确执行使得数据库从一种状态转换成另外一种状态(简单理解为对数据的一次操作过程就是一个事务)。
对数据库的一次操作就是一个事务,在一个事务中可能要执行多条sql语句
事务的回滚和提交
在进行数据库操作的过程中可能会在一次功能实现中执行多个更新语句(增加,删除,修改)
比如说转账过程:A转账1000W给B
1、在A账户上减少1000W(要执行一个减少A账户存款的sql语句)
2、在B账户上增加1000W(手续费不算,要执行一个增加B账户存款的sql语句)
在以上的过程中会出现这样的情况,在减少A账户的存款之后,此时系统出现了一个未知错误,导致了B账户上的金额没有增加
此时的解决方案:只有所有的sql语句都成功执行之后才能进行事务的提交(数据库中使用COMMIT命令),若在执行的过程中只要有一条sql语句出现了错误或者异常则让事务进行回滚(撤销已经执行成功了的sql语句,数据库中事务的回滚的命令是ROLLBACK)
ROLLBACK:事务回滚(如果中途出现了异常则可以使用该命令回滚)
COMMIT:事务提交(中途没有出现任何问题则提交),提交之后的数据不能再回滚
2、多用户下的死锁
在多个用户同是操作一条数据的时候,如果前面一个用户进行了数据更新,但是没有使用COMMIT命令进行事务的提交,则后面一个用户就不能操作当前数据,只有等待上一个用户提交或者混滚事务之后才能进行操作
在数据库中如果某个用户正在对一条数据进行更新操作,这时会获得一把锁,对正在更新的数据上锁,只能当前用户占有,只能当前用户操作该数据,而其他用户不能操作该数据,在操作完成之后,释放锁。释放完锁之后,其它用户才能进行操作,这也是一种悲观锁(认为数据一定为出现安全问题,所以就要锁定),也是独占锁(与共享锁是相对的),那么在什么情况下任务数据操作完毕了呢?
两种情况:提交事务、事务回滚、
发现当多个用户操作同一条数据的时候,只有上一个用户提交或者回滚了事务之后下一个用户才能进行操作,否则下一个用户处于线程阻塞状态。
因为在进行更新数据的时候数据库会给数据上锁,这是指的是行级锁,锁定一行的数据。
以上的操作都是更新语句,如果是查询语句存在死锁吗?
比如说上一个用户是查询的语句,下一个语句时更新语句,后一个用户会阻塞吗?默认情况下是不会的。
如果要让查询语句也能出现死锁的现象,我们可以在查询语句之后增加一个关键字FOR UPDATE
其实数据库提供的锁机制的是一种悲观锁,此外还有乐观锁,乐观锁是通过控制版本号或者时间戳来实现的一种锁机制,要结合程序才能实现
补充:悲观锁与乐观锁
悲观锁与乐观锁的区别
悲观锁认为数据更新时一定会发生冲突,因此需要对记录加锁,以保证数据的一致性。oracle在数据更新时通常是悲观锁,因其为行级锁,具有较好的性能,通常针对并发使用
乐观锁与其不同,它认为数据不存在冲突,因此,需要在提交时保证数据一致性,如果不一致,则返回错误,由程序本身的逻辑进行处理(通过在表中增加版本戳列,来标识是否发生了变化)