多用户访问会遇到问题,同时访问一个数据,修改,到底哪个用户说了算
myisam存储引擎是表级锁,innodb行级锁,mvcc机制(多版本并发控制,也可以在一定程度上提高并发访问,同时对数据库记录进行修改)
读锁只能,读不能写,(做备份的时候,备份是基于时间点的数据,备份完了才能进行修改)
写锁,独占锁,将只能自己访问数据,别人不能读
存储引擎会自动加锁,也可以服务器自己用户加锁
read读锁,只读不可写,write,排他锁,你在访问,其他人就访问不了
前面创建了表,立即加了一个写锁,加完数据再释放锁
表和表有关系这样就会存在一些问题,将来写代码需要考虑
开两个终端连接数据库
重新导入数据
当前tearcher表加了个读锁,不能加入数据
别的终端插入会一直等你释放,本终端会提示拒绝
解锁 unlock tables
另外终端就立即更新成功
写锁意味排他,但是自己能读能写
别的终端就无法读
释放之后就马上可以读了
再次加锁
另外终端再查就会去缓存里查了,不会拒绝你通过缓存查询的
可以设置不允许使用查询缓存,默认OFF,即时加锁,也允许从缓存得到数据
退出重新登录
再加上写锁
其他终端就不让查了
unlock tables解锁
查几次,应该有缓存了
再次枷锁
加了锁就不行了
结合锁就涉及到事务并发的问题
ACID特性
对数据库的数据进行修改,第一步先放到内存,100,100修改成200,第二部先把更改写到日志里,update 100=200,第三步吧数据库更改写到磁盘里
假如现在有三条不同操作,三条事务都做完了才会提交,数据库完成更改
这时候内存数据丢了,只有第一步第二步完成了,事务不完整,吧刚才做过的事务日志撤销,就是rollback回滚或者undo撤销
可能还有另外一种情况,有多个事务,之前的事务结束了,是一个完整的事务,但是不一定事务结束了,就立即把数据写到磁盘里
因为什么时候写是根据系统是否空闲来决定的,
做到45的时候系统停电了,就会发现45这个事务出现问题,就把这个从事务日志中撤销,前面123做完了,是一个完整的事务,就会在磁盘上执行,redo操作。
保证事务完成的,数据库就留得住
数据库始终存一致状态,比如银行转账
事务没结束,没改完的数据叫脏数据,需要隔离的,希望别人不要看到
事务提交,就是永久保存在数据库,无法后悔
**,初始化数据库 initial db state
开始一个事务 start transaction
增删改,查询不算一个事务部分,只有增删改才会记录在事务日志里
commit提交 数据库状态就发生变化
rollback 回滚
**
通常有两种事务,一种是显性事务 手动提交,一种是隐性事务 自动提交
mysql默认隐性事务,默认执行增删改就commit
oracle默认不会自动提交,必须明确写commit才能提交
@@两个代表系统变量,@一个代表自定义变量
默认autocommit=1,只要进行修改马上就提交
可以修改成非自动提交
自己添加数据是可以看到的
另外终端看不到,因为是脏数据
现在可以撤销
如果要多个语句执行,想提高效率,最后再commit
开启事务了,只要不commit就不会提交事务
rollback撤销,8,9行就没了
现在rollback没有用了,已经自动提交了
现在清空表
开启事务,速度很快,事务不仅保证安全,效率比一条条commit来的速度快
事务还可以部分撤销
在事务的执行的时候,还有个保存事务执行节点,
可以在执行事务的时候 ,定义一个位置,带来的好处就是,可以在标签的地方,选择性的撤销
如果没有标签,之前rollback是全部都撤销了
事务的隔离级别严重的影响了多个事务并发访问数据库的表现
隔离级别分成4个:
read uncommitted 读到未提交的数据,t1事务还未结束,t2就能看到了,脏数据
READ COMMITED 不可重复读,能查看提交的数据,未提交的看不到,叫不可重复读, 因为多个事务再修改的时候,导致你每次看到的数据都不一样
每次读取的数据都不一样
REPEATABLE READ 可重复读,就有要求,至少在你这个事务里看到的数据是一样的,就有可重复读,保证一个事务里,数据是一致的
也就是实际数据发生改变,但是在B事务的生命期里看到的还是以前的,造成幻读,自我欺骗,这样可以执行备份命令,在备份期间,别人持续修改数据,无所谓,对并发是没什么影响的
SERIALIZABILE,未提交的读事务将阻塞另外一个修改事务,就不会造成之前的问题,数据是最稳定的但是并发性能差
设置事务的隔离级别
tx_isloatinotallow=事务的隔离级别来设置目前的状态是重复读
修改成不可重复读,这样不是可以永久保存的
永久保存,写到配置文件里
是个变量不是服务器选项,不能写到配置文件里
要写成这样
开启一个事务
另外的终端是可以看到的,因为隔离级别的read-uncommited,(可以看到脏数据)
撤销了
另外的终端再次查看就没了
还可以改成另外的隔离级别,READ-COMMITED,不可重复读
开启事务,增加数据
另外的终端也开启事务
提交修改的
另外的终端可以看到提交的,也就是在同一个事务期间看到的数据可能不一样
注释掉,默认隔离级别是可重复读, REPEATABLE-READ
另外终端看到的仍然是8条
另外的终端开启一个事务
提交
另外的终端还是看到8个,系统默认的可重复读
事务提交了就能看到别人改的数据了
两个终端都开启事务
一个事务开启了读,另外的就改不了
事务的未提交读会阻塞写
就成功了
再次开启一个事务
不让查,因为另外一遍的写操作没提交
未提交的写操作阻塞读事务删除可以后悔,rollback
**撤销不是万能的,只能针对增删改,DDL语言撤销不来,数据库的定义语言(创建表,修改表,删除表),trancate ,drop撤销不来
撤销的是DML(增删改) **
MVCC是在每个表加两个字段,create,delete,确保事务一致性,在READ UNCOMMITED是不起作用的,可以看到脏数据,串行化也是不起作用的
串行化,会加锁,锁住这个资源,不让别人访问
另外的终端开启事务,是看到没有改的数据
同时修改数据
换成另外一条记录就可以修改
innodb是行级锁,如果两个改,一个人改了一般,离开了,但是没提交,导致一直锁着,别人无法修改
有个超时时长
可以把进程2删除,因为这是另外一个终端修改的进程
另外的终端就成功了,刚才的直接杀掉进程了
被踢出来了
通讯双方多个事务执行,出现死锁,就需要避免