无论是在操作系统还是在数据库中,都不免有进程并发的操作,而进程并发不就难免会造成数据的错误(也称为时间的错误)
在操作系统中运用的是Pv操作解决并发的问题,今天我想说的是在数据库中如何避免并发带来的三个问题
1丢失更新的问题
2读取数据问题
3不可重复读问题
下面用例子来说明该问题
丢失更新的问题
丢失更新原因就在于 多个事务同时对一个数据操作,每个事务都不知道其它事务的存在。最后的更新将重写由其它事务所做的更新。
例如:
当事务A和事务B同时修改某行的值,
1.事务A将数值改为1并提交
2.事务B将数值改为2并提交。这时数据的值为2,事务A所做的更新将会丢失。
时间 | 更新事务A | 数据库中a的值 | 更新事务B |
T0 |
| 100 |
|
T1 | Find a |
|
|
T2 |
|
| Find a |
T3 | a:=a-30 |
|
|
T4 |
|
| a:=a*20 |
T5 | Upd a |
|
|
T6 |
| 70 | Upd a |
T7 |
| 200 |
|
上面的实例我们可以看到,当程序正确执行的时候,结果是140或170。但是按表中的并发执行,结果A是200,原因就在于事务A的更新被事务B的被重写覆盖掉了,导致事务A的丢失。
读脏数据
在数据库技术中。我们把未提交随后被撤销的数据称为“脏数据”。
看实例
·
1.Mary的原工资为1000,财务人员将Mary的工资改为了8000(但未提交事务)
2.Mary读取自己的工资,发现自己的工资变为了8000,欢天喜地!(在缓存中读取)
3.而财务发现操作有误,回滚了事务,Mary的工资又变为了1000像这样,Mary记取的工资数8000是一个脏数据。
不可重复读
不可重复读,主要是同一个事务前后两次读取的结果不一致造成的
实例
1.在事务1中,Mary 读取了自己的工资为1000,操作并没有完成
2.在事务2中,这时财务人员修改了Mary的工资为2000,并提交了事务.
3.在事务1中,Mary 再次读取自己的工资时,工资变为了2000
事务1前后两次读取同一个数据出现不同的结果。这就造成的数据的不可重复读的问题。
以上三个问题是数据库事务并发中经常出现的问题。如何避免出现该问题呢。就需要对数据进行加锁。锁的问题下篇博客精彩讲述。