日期:2014-05-16  浏览次数:20536 次

未知驱动学习--数据库中的悲观锁和乐观锁实例

        第一次接触这个名词,悲观锁,不知道是谁起的这样的名字. 很想知道为什么叫做悲观锁, 自己在占用一个东西的时候不允许别人碰就是悲观了(⊙_⊙)?这可能是理智的一种选择. 当然因为学习和生活即是相同的又是不同的, 我们可以这样解释的.

 

悲观锁是对数据的冲突采取一种悲观的态度, 比如上自习占座, 假设一定会有人和我抢一个座位, 我在最开始就把这个座位的时候,我就把这过座位贴上我的标签, 不允许任何人使用. 而乐观锁是我认为不一定有人和我抢座, 只有当我真正的要用到这个座位的时候再去看看这个座位上是否有人.  这就相当于, 有些人在发生一些事的时候总会把事情想坏,有的人则会把事情向好的方面想.

 

 

当然在数据库中我们可以这样解释, 悲观锁对数据的冲突采取的是一种悲观的态度, 就是数据肯定会冲突, 所以在开始读数据的时候就把数据锁住, 而乐观锁就是认为数据一般不会起冲突, 所以在数据进行提交更新的时候, 才会对数据冲突进行检测, 如果冲突了, 则让用户返回错误的信息, 让用户决定如何去做. 

 

        哪种情况使用悲观锁,哪种情况使用乐观锁?

        针对数据并发的可能性比较大, 我们用悲观锁. 如果并发的可能性比较小, 我们用乐观锁.

 

        悲观锁实例:


        例如我们对oracle中的一个表进行修改更新操作, 但是在修改的时候首先要从数据库中读取出来这条要修改的内容, 悲观锁是在读取这条数据的时候就把表中的这条记录锁定, 不允许其他的用户来读取.

        这样,我们数据库中的查询语句:

       String sql="select value from T_TABLE_ID where table_name=? for update";

        因为我们在连接数据库,执行操作的时候, 数据库会自动的提交事务, 我们需要把读取和更新这条记录放在一个事务里, 所以我们就要手动的去控制, 让我们读取更新全部完成的时候再提交事务.

 

        1 所以先把事务"开关"自动变手动 , 就像开车的时候, 我们有手动挡和自动挡一样~~~

 

        所以我们在jsp的后台页面上数据库工具类中添加方法的代码:

        自动提交变手动提交事务:

	//自己封装的让事务变成非自动回滚的函数. .
	public static void beginTransaction(Connection conn)
	{
		try{
			if(conn!=null)
			{
				if(conn.getAutoCommit())
				{
					//手动提交. 如果是true,则变为false.
					conn.setAutoCommit(false);
				}
			}
		}catch(SQLException e){
			
		}
	}

 

        这里面有一个jdbc的参数,  connection的方法setAutoCommit()方法, true: 表示sql命令提交(commit) 由驱动程序负责    false: sql 命令提交由应用程序负责, 程序必须调用commit方法或rollback方法.

 

 

        提交事务:

	//提交事务.
	public static void commitTransaction(Connection conn)
	{
		try{
			if(conn!=null)
			{
				if(!conn.getAutoCommit())
				{
					//手动提交. 如果是true,则变为false.
					conn.commit()