高并发请求中的读写锁
博客专区 > IamOkay 的博客 > 博客详情
高并发请求中的读写锁
IamOkay 发表于3年前
高并发请求中的读写锁
  • 发表于 3年前
  • 阅读 971
  • 收藏 10
  • 点赞 0
  • 评论 0

腾讯云 新注册用户 域名抢购1元起>>>   

摘要: 在web系统设计中,主要处理的是同步问题和高并发问题,权限问题等
  1. 在数据库中使用读写锁

数据库中使用读写锁,这样能更好地读取某一类统计数据,但一般读取不应该加锁,但修改操作却要慎重

事务的特性

 1. 原子性(atomic),事务必须是原子工作单元;对于其数据修改,要么全都执行,要么全都不执行

 2. 一致性(consistent),事务在完成时,必须使所有的数据都保持一致状态。

 3. 隔离性(insulation),由并发事务所作的修改必须与任何其它并发事务所作的修改隔离。

 4. 持久性(Duration),事务完成之后,它对于系统的影响是永久性的。

在j2ee中,hirbernate提供了悲观所和乐观锁,但悲观锁的使用同样也限制了读取的并发性,因此很少使用,二使用最多的是添加乐观锁,在记录中添加版本version或者时间戳字段,这样做并不影响读取,只是按照版本控制的思维来限制低版本记录修改操作,当然有人要问,低版本记录有新的数据,怎么才能更新。

①开启事务->②更新记录前,读取一次最新的数据->③提交->@回滚或者提交事务。

如何保持version和timestamp呢,在提交的过程中,将version或者timestramp进行更新。


参考:http://blog.sina.com.cn/s/blog_4c197d420101awhc.html

           http://blog.sina.com.cn/s/blog_4c197d420101awhc.html

           http://www.cnblogs.com/otomedaybreak/archive/2012/01/27/2330008.html

2.mysql的事务操作

<?php
$handler=mysql_connect("localhost","root","");
mysql_select_db("task");
mysql_query("SET AUTOCOMMIT=0");//设置为不自动提交,因为MYSQL默认立即执行
mysql_query("BEGIN");//开始事务定义
if(!mysql_query("insert into trans (id) values('2')"))
{
mysql_query("ROOLBACK");//判断当执行失败时回滚
}
if(!mysql_query("insert into trans (id) values('4')"))
{
mysql_query("ROOLBACK");//判断执行失败回滚
}
mysql_query("COMMIT");//执行事务
mysql_close($handler);
?>

3.文件读写锁来解决高并发中的读写问题,当然也可以使用线程同步的方式,进行文件完整性保护

java中实现文件读写锁,就是锁住读写通道

 FileChannel

public class Thread_readFile extends Thread{  
    public void run(){  
        try {  
            Calendar calstart=Calendar.getInstance();  
            sleep(5000);  
            File file=new File("D:/test.txt");      
              
            //给该文件加锁  
            RandomAccessFile fis = new RandomAccessFile(file, "rw"); 
            FileChannel fcin=fis.getChannel();  
            FileLock flin=null;  
            while(true){  
                try {
			flin = fcin.tryLock();
					break;
			} catch (Exception e) {
					 System.out.println("有其他线程正在操作该文件,当前线程休眠1000毫秒"); 
					 sleep(1000);  
			}
				
            }  
            byte[] buf = new byte[1024];  
            StringBuffer sb=new StringBuffer();  
            while((fis.read(buf))!=-1){                  
                sb.append(new String(buf,"utf-8"));      
                buf = new byte[1024];  
            }  
              
            System.out.println(sb.toString());  
              
            flin.release();  
            fcin.close();  
            fis.close();  
            fis=null;  
              
            Calendar calend=Calendar.getInstance();  
            System.out.println("读文件共花了"+(calend.getTimeInMillis()-calstart.getTimeInMillis())+"秒");  
        }catch (FileNotFoundException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
    }  
}

 写

public class Thread_readFile extends Thread{  
    public void run(){  
        try {  
            Calendar calstart=Calendar.getInstance();  
            sleep(5000);  
            File file=new File("D:/test.txt");      
              
            //给该文件加锁  
            RandomAccessFile fis = new RandomAccessFile(file, "rw"); 
            FileChannel fcin=fis.getChannel();  
            FileLock flin=null;  
            while(true){  
                try {
					flin = fcin.tryLock();
					break;
				} catch (Exception e) {
					 System.out.println("有其他线程正在操作该文件,当前线程休眠1000毫秒"); 
					 sleep(1000);  
				}
				
            }  
            byte[] buf = new byte[1024];  
            StringBuffer sb=new StringBuffer();  
            while((fis.read(buf))!=-1){                  
                sb.append(new String(buf,"utf-8"));      
                buf = new byte[1024];  
            }  
              
            System.out.println(sb.toString());  
              
            flin.release();  
            fcin.close();  
            fis.close();  
            fis=null;  
              
            Calendar calend=Calendar.getInstance();  
            System.out.println("读文件共花了"+(calend.getTimeInMillis()-calstart.getTimeInMillis())+"秒");  
        }catch (FileNotFoundException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
    }  
}


共有 人打赏支持
粉丝 165
博文 405
码字总数 301129
×
IamOkay
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: