javaWeb知识之——数据库


  1. 什么是Sql注入,如何防止Sql注入?
  • 所谓的sql注入就是攻击者将命令插入到WEB表单的输入域或者页面请求的查询字符串,
    欺骗服务器,执行恶意的SQL命令,
  • 在某些表单中,用户输入的内容直接用来构造动态SQL命令,
    或者作为存储过程的输入参数,这类表单特别容易受到SQL注入式攻击。

参考代码:

假如某个网站使用账户名密码登录的验证SQL语句是:
select *  from users wherer username="" and password= "" ; 
攻击者在表单中输入账户名" or 1=1 --密码为空,则查询语句变成了:
 select * from users where username=""or 1=1 --"and password="" ;
    --在SQL中为注释,后面的都不执行,整个执行的语句变成了
 select * from users where username=" or 1=1 ;
//这句语句是永远能成功执行的
更有甚者,攻击者使用语句
 select * from users where username="; DROP Database (DB Name) 
  -- "and password="";
网站就变的危险了。

防止措施:

  1. 最常用的,采用预编译语句集PreparedStatement;
  2. 使用正则表达式将单引号,分号,和注释号–的语法给替换掉
    public static String TransactSQLInjection(String str){
    return str.replaceAll(“.([‘;]+|(–)+).“, ” “);
    }
  3. 严格区分管理员和普通用户权限
  4. 使用过滤器过滤一些字符串

2.数据库死锁是如何产生的?

2.1 死锁定义

当多个进程同时访问一个数据库时,其中的每个进程拥有的资源都是其他进程所需的,
 由此造成的每个进程都无法继续下去的情况

2.2 产生的原因

一个进程需要访问数据库表或者字段的时候,另外一个进程正在执行带锁的访问,那么
这个进程就会等待,当等待很久锁还没有解除的话,就会锁超时,报告一个拒绝执行的SQL操作。
说白了,就是事务的控制导致。

2.3 减少和防止死锁的方法

- 按统一顺序进行访问
 - 避免事务中的用户交互
 - 降低事务的隔离级别    
 - 保持事务在同一个批处理中
 - ....

3.事务的隔离级别有哪些?

Msyql数据库的事务级别有四个:

- 1.未提交读:read uncommitted 脏读,不重复读,虚读 都有可能发生
 - 2.已提交读:read committed 避免脏读,但是不可重复读,虚读都有可能发生
 - 4.可重复读: repeatable read 避免脏读,不可重复读,但是虚读有可能发生 
 - 8.串行化 :serializable 避免了脏读,不可重复读,虚读的发生。

Msql默认级别是repeatable,Orcale默认级别是read committed

查询事务级别语句:select @@tx_isolation
更新事务级别的语句:set session transaction isolation level 事务级别

4.说说乐观锁,悲观锁以及其应用场景

数据丢失是数据库中常见的一类问题,丢失更新一般有两个解觉方案:

4.1 乐观锁解决

乐观锁认为丢失更新不会发生,解决方式是:
    在数据库表中插入一个额外的字段,就做版本最开始有一个版本,一旦更新一次,
就会有新的版本,如果一个事务在更新的时候,发现本地现有拿到的数据版本与服务器
中表的版本不一致,就会重新查询一下,重新再改。

4.2 悲观锁解决

悲观锁认为丢失更新一定会发生,解决的方法是: 
    利用数据库自带的锁机制来实现,关系型数据库有两种锁,其中有一种叫做排他锁,
悲观锁使用排他锁,将当前要被修改的那一行数据锁定起来,锁住后其他事务不可以去更新
它,直到当前的事务解决了,这个锁被释放了,其他事务才可以去修改。

4.3 悲观锁和乐观锁的选择

这两种没有说哪一种就一定好于另一种,需要在不同的应用场景下选择。
乐观锁适用于写比较少的情况,即冲突比较少发生的情况下,这样可以提高系统的吞吐量,
但是如果冲突经常发生,上层应用会不断的retry,遮掩反倒会降低性能,这个时候使用
悲观锁就比较合适。