javaWeb知识之——数据库
- 什么是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="";
网站就变的危险了。
防止措施:
- 最常用的,采用预编译语句集PreparedStatement;
- 使用正则表达式将单引号,分号,和注释号–的语法给替换掉
public static String TransactSQLInjection(String str){
return str.replaceAll(“.([‘;]+|(–)+).“, ” “);
} - 严格区分管理员和普通用户权限
- 使用过滤器过滤一些字符串
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,遮掩反倒会降低性能,这个时候使用
悲观锁就比较合适。