DBHelper (支持事务与数据库变更)
1 概述
更新内容:添加 "支持数据分页"
这个数据库操作类的主要特色有
1> 事务操作更加的方便
2> 变更数据库更加的容易
3> 支持数据分页
Normal
0
7.8 磅
0
2
false
false
false
EN-US
ZH-CN
X-NONE
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:普通表格;
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-priority:99;
mso-style-parent:"";
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin:0cm;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.5pt;
mso-bidi-font-size:11.0pt;
font-family:"Calibri","sans-serif";
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:"Times New Roman";
mso-bidi-theme-font:minor-bidi;
mso-font-kerning:1.0pt;}
最新的所有代码:
using System;
using System.Data;
using System.Data.Common;
using Project.BaseFramework;
using System.Collections.Generic;
using System.Configuration; namespace Project.BaseFramework.DataProvider
{
public class DBHelper
{ #region Constuctor
public DBHelper() { } private static string ConnectionString = ConfigurationManager.AppSettings["DBConnectionString"]; private static IDBClient DBClient = DBClientFactory.GetDBClient(ConfigurationManager.AppSettings["DBClient"]); [ThreadStatic]
private static TransConnection TransConnectionObj = null; #endregion #region ExecuteNonQuery
public static int ExecuteNonQuery(CommandType cmdType, string cmdText, params DbParameter[] parameterValues)
{
int result = ;
bool mustCloseConn = true; DbCommand cmd = PrepareCmd(cmdType, cmdText, parameterValues, out mustCloseConn);
OpenConn(cmd.Connection);
result = cmd.ExecuteNonQuery(); if (mustCloseConn) CloseConn(cmd.Connection);
ClearCmdParameters(cmd);
cmd.Dispose(); return result;
} #endregion ExecuteNonQuery #region ExecuteScalar
public static object ExecuteScalar(CommandType cmdType, string cmdText, params DbParameter[] parameterValues)
{
object result = ;
bool mustCloseConn = true; DbCommand cmd = PrepareCmd(cmdType, cmdText, parameterValues, out mustCloseConn);
OpenConn(cmd.Connection);
result = cmd.ExecuteScalar(); if (mustCloseConn) CloseConn(cmd.Connection);
ClearCmdParameters(cmd);
cmd.Dispose(); return result;
}
#endregion ExecuteScalar #region ExecuteReader
public static DbDataReader ExecuteReader(CommandType cmdType, string cmdText, params DbParameter[] parameterValues)
{
DbDataReader result = null;
bool mustCloseConn = true;
DbCommand cmd = PrepareCmd(cmdType, cmdText, parameterValues, out mustCloseConn);
try
{
OpenConn(cmd.Connection);
if (mustCloseConn)
{
result = cmd.ExecuteReader(CommandBehavior.CloseConnection);
}
else
{
result = cmd.ExecuteReader();
}
ClearCmdParameters(cmd);
return result;
}
catch (Exception ex)
{
if (mustCloseConn) CloseConn(cmd.Connection);
ClearCmdParameters(cmd);
cmd.Dispose();
throw ;
}
}
#endregion ExecuteReader #region ExecuteDataset
public static DataSet ExecuteDataSet(CommandType cmdType, string cmdText, params DbParameter[] parameterValues)
{
DataSet result = null;
bool mustCloseConn = true; DbCommand cmd = PrepareCmd(cmdType, cmdText, parameterValues, out mustCloseConn);
using (DbDataAdapter da = DBClient.GetDbDataAdappter())
{
da.SelectCommand = cmd;
result = new DataSet(); da.Fill(result);
} if (mustCloseConn) CloseConn(cmd.Connection);
ClearCmdParameters(cmd);
cmd.Dispose(); return result;
}
#endregion ExecuteDataset #region ExecuteDataTable
public static DataTable ExecuteDataTable(CommandType cmdType, string cmdText, params DbParameter[] parameterValues)
{
DataSet ds = ExecuteDataSet(cmdType,cmdText, parameterValues);
if (ds != null && ds.Tables.Count > )
return ds.Tables[];
else
return null;
}
#endregion #region ExecutePaging
public static DataTable ExecutePagingDataTable(CommandType cmdType, string cmdText,int pageIndex,int pageSize,string orderInfo, params DbParameter[] parameterValues)
{
cmdText = DBClient.GetPagingSql(cmdText, pageIndex, pageSize, orderInfo);
return ExecuteDataTable(CommandType.Text, cmdText, parameterValues);
} public static DbDataReader ExecutePagingReader(CommandType cmdType, string cmdText, int pageIndex, int pageSize, string orderInfo, params DbParameter[] parameterValues)
{
cmdText = DBClient.GetPagingSql(cmdText, pageIndex, pageSize, orderInfo);
return ExecuteReader(CommandType.Text, cmdText, parameterValues);
}
#endregion #region Transaction
public static void BeginTransaction()
{
if (TransConnectionObj == null)
{
DbConnection conn = DBClient.GetDbConnection(ConnectionString);
OpenConn(conn);
DbTransaction trans = conn.BeginTransaction();
TransConnectionObj = new TransConnection();
TransConnectionObj.DBTransaction = trans;
}
else
{
TransConnectionObj.Deeps += ;
}
} public static void CommitTransaction()
{
if (TransConnectionObj == null) return;
if (TransConnectionObj.Deeps > )
{
TransConnectionObj.Deeps -= ;
}
else
{
TransConnectionObj.DBTransaction.Commit();
ReleaseTransaction();
}
} public static void RollbackTransaction()
{
if (TransConnectionObj == null) return;
if (TransConnectionObj.Deeps > )
{
TransConnectionObj.Deeps -= ;
}
else
{
TransConnectionObj.DBTransaction.Rollback();
ReleaseTransaction();
}
} private static void ReleaseTransaction()
{
if (TransConnectionObj == null) return;
DbConnection conn = TransConnectionObj.DBTransaction.Connection;
TransConnectionObj.DBTransaction.Dispose();
TransConnectionObj = null;
CloseConn(conn);
} #endregion #region Connection
private static void OpenConn(DbConnection conn)
{
if (conn == null) conn = DBClient.GetDbConnection(ConnectionString);
if (conn.State == ConnectionState.Closed) conn.Open();
} private static void CloseConn(DbConnection conn)
{
if (conn == null) return;
if (conn.State == ConnectionState.Open) conn.Close();
conn.Dispose();
conn = null;
}
#endregion #region Create DbParameter public static DbParameter CreateInDbParameter(string paraName, DbType type, int size, object value)
{
return CreateDbParameter(paraName, type, size, value, ParameterDirection.Input);
} public static DbParameter CreateInDbParameter(string paraName, DbType type, object value)
{
return CreateDbParameter(paraName, type, , value, ParameterDirection.Input);
} public static DbParameter CreateOutDbParameter(string paraName, DbType type, int size)
{
return CreateDbParameter(paraName, type, size, null, ParameterDirection.Output);
} public static DbParameter CreateOutDbParameter(string paraName, DbType type)
{
return CreateDbParameter(paraName, type, , null, ParameterDirection.Output);
} public static DbParameter CreateReturnDbParameter(string paraName, DbType type, int size)
{
return CreateDbParameter(paraName, type, size, null, ParameterDirection.ReturnValue);
} public static DbParameter CreateReturnDbParameter(string paraName, DbType type)
{
return CreateDbParameter(paraName, type, , null, ParameterDirection.ReturnValue);
} public static DbParameter CreateDbParameter(string paraName, DbType type, int size, object value, ParameterDirection direction)
{
DbParameter para = DBClient.GetDbParameter(); para.ParameterName = paraName; if (size != )
{
para.Size = size;
} para.DbType = type; if (value != null)
{
para.Value = value;
}
else
{
para.Value = DBNull.Value;
} para.Direction = direction; return para;
} #endregion #region Command and Parameter
/// <summary>
/// 预处理用户提供的命令,数据库连接/事务/命令类型/参数
/// </summary>
/// <param>要处理的DbCommand</param>
/// <param>数据库连接</param>
/// <param>一个有效的事务或者是null值</param>
/// <param>命令类型 (存储过程,命令文本, 其它.)</param>
/// <param>存储过程名或都T-SQL命令文本</param>
/// <param>和命令相关联的DbParameter参数数组,如果没有参数为'null'</param>
/// <param><c>true</c> 如果连接是打开的,则为true,其它情况下为false.</param>
private static DbCommand PrepareCmd(CommandType cmdType,string cmdText, DbParameter[] cmdParams, out bool mustCloseConn)
{
DbCommand cmd = DBClient.GetDbCommand(cmdText); DbConnection conn = null;
if (TransConnectionObj != null)
{
conn = TransConnectionObj.DBTransaction.Connection;
cmd.Transaction = TransConnectionObj.DBTransaction;
mustCloseConn = false;
}
else
{
conn = DBClient.GetDbConnection(ConnectionString);
mustCloseConn = true;
}
cmd.Connection = conn; cmd.CommandType = cmdType; AttachParameters(cmd, cmdParams); return cmd;
} /// <summary>
/// 将DbParameter参数数组(参数值)分配给DbCommand命令.
/// 这个方法将给任何一个参数分配DBNull.Value;
/// 该操作将阻止默认值的使用.
/// </summary>
/// <param>命令名</param>
/// <param>SqlParameters数组</param>
private static void AttachParameters(DbCommand command, DbParameter[] commandParameters)
{
if (command == null) throw new ArgumentNullException("command");
if (commandParameters != null)
{
foreach (DbParameter p in commandParameters)
{
if (p != null)
{
// 检查未分配值的输出参数,将其分配以DBNull.Value.
if ((p.Direction == ParameterDirection.InputOutput || p.Direction == ParameterDirection.Input) &&
(p.Value == null))
{
p.Value = DBNull.Value;
}
command.Parameters.Add(p);
}
}
}
} private static void ClearCmdParameters(DbCommand cmd)
{
bool canClear = true;
if (cmd.Connection != null && cmd.Connection.State != ConnectionState.Open)
{
foreach (DbParameter commandParameter in cmd.Parameters)
{
if (commandParameter.Direction != ParameterDirection.Input)
{
canClear = false;
break;
}
}
}
if (canClear)
{
cmd.Parameters.Clear();
}
}
#endregion
}
} using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Common; namespace Project.BaseFramework.DataProvider
{
internal class TransConnection
{
public TransConnection()
{
this.Deeps = ;
} public DbTransaction DBTransaction { get; set; } public int Deeps { get; set; }
}
} using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Common;
using System.Data.SqlClient; namespace Project.BaseFramework.DataProvider
{
public interface IDBClient
{
DbConnection GetDbConnection(string connectionString); DbCommand GetDbCommand(string cmdText); DbDataAdapter GetDbDataAdappter(); DbParameter GetDbParameter(); string GetPagingSql(string cmdText, int pageIndex, int pageSize, string orderInfo);
}
} using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Common;
using System.Data.SqlClient; namespace Project.BaseFramework.DataProvider
{
public class SqlServerClient:IDBClient
{
public DbConnection GetDbConnection(string connectionString)
{
return new SqlConnection(connectionString);
} public DbCommand GetDbCommand(string cmdText)
{
return new SqlCommand(cmdText);
} public DbDataAdapter GetDbDataAdappter()
{
return new SqlDataAdapter();
} public DbParameter GetDbParameter()
{
return new SqlParameter();
} public string GetPagingSql(string cmdText, int pageIndex, int pageSize, string orderInfo)
{
int startIndex = (pageIndex - ) * pageSize;
int endIndex = startIndex + pageSize + ;
cmdText = string.Format(@";WITH T1 AS({0}),T2 AS(SELECT *,ROW_NUMBER()OVER ({1}) AS _RowNum FROM T1)
SELECT *FROM T2
WHERE _RowNum>{2} AND _RowNum<{3}",cmdText,orderInfo,startIndex,endIndex);
return cmdText;
}
}
} using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Common;
using MySql.Data.MySqlClient; namespace Project.BaseFramework.DataProvider
{
public class MySqlClient:IDBClient
{
public DbConnection GetDbConnection(string connectionString)
{
return new MySqlConnection(connectionString);
} public DbCommand GetDbCommand(string cmdText)
{
return new MySqlCommand(cmdText);
} public DbDataAdapter GetDbDataAdappter()
{
return new MySqlDataAdapter();
} public DbParameter GetDbParameter()
{
return new MySqlParameter();
} public string GetPagingSql(string cmdText, int pageIndex, int pageSize, string orderInfo)
{
int startIndex = (pageIndex - ) * pageSize;
cmdText = string.Format(@"{0} {1} Limit {2}, {3}", cmdText, orderInfo, startIndex,pageSize);
return cmdText;
}
}
} using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Reflection; namespace Project.BaseFramework.DataProvider
{
public class DBClientFactory
{
private static readonly string path = "Project.BaseFramework"; public static IDBClient GetDBClient(string dbClientClassName)
{
if(string.IsNullOrEmpty(dbClientClassName))
dbClientClassName="SqlServerClient";
string className = string.Format("{0}.DataProvider.{1}", path, dbClientClassName);
return (IDBClient)Assembly.Load(path).CreateInstance(className);
}
}
}
配置文件
<appSettings>
<add key="DBConnectionString" value="Data Source=.;Initial Catalog=ProjectData;Persist Security Info=True;User ID=sa;Password=kjkj,911;"/>
<add key="DBClient" value="SqlServerClient"/>
</appSettings>
2 事务操作
2.1 单个事务操作示例
try
{
DBHelper.BeginTransaction();
// add
DBHelper.ExecuteNonQuery(CommandType.Text, "INSERT INTO TRole(ID,RoleName) VALUES('R1','MKT')"); //detele by pk
DBHelper.ExecuteNonQuery(CommandType.Text, "DELETE FROM TRole WHERE ID='R1'"); Console.WriteLine(string.Format("Success and Commited"));
DBHelper.CommitTransaction();
}
catch (Exception ex)
{
Console.WriteLine(string.Format("Exception and rollback"));
DBHelper.RollbackTransaction();
}
用法是:只需要把相关联的代码放在BeginTransaction和CommitTransaction中间,如果发生异常调用RollbackTransaction即可。
实现事务的方法是:
首先,DBHelper维护一个TransConnection类型的字段,并添加ThreadStatic. ThreadStatic可以维护在线程级别上的唯一性。
[ThreadStatic]
private static TransConnection TransConnectionObj = null;
其次,TransConnection的作用是保存事务,并记录嵌套事务的嵌套级别。
internal class TransConnection
{
public TransConnection()
{
this.Deeps = ;
} public DbTransaction DBTransaction { get; set; } public int Deeps { get; set; }
}
最后,当调用 BeginTransaction时创建TransConnection对象。之后的多个DbCommand命令都从这个事务上拿连接。因为TransConnectionObj添加了ThreadStatic属性,所以它是线程唯一的,不会影响其它线程上的事务;所有方法执行完后,调用CommitTransaction 就提交事务,并关闭连接;如果发生异常,则调用RollbackTransaction,就会回滚所有命令,并关闭连接。
2.2 嵌套事务示例
static void Main(string[] args)
{ try
{
DBHelper.BeginTransaction(); // add
DBHelper.ExecuteNonQuery(CommandType.Text, "INSERT INTO TRole(ID,RoleName) VALUES('R1','MKT')"); Transaction2(); //detele by pk
DBHelper.ExecuteNonQuery(CommandType.Text, "DELETE FROM TRole WHERE ID='R1'"); Console.WriteLine(string.Format("Success and Commited"));
DBHelper.CommitTransaction();
}
catch (Exception ex)
{
Console.WriteLine(string.Format("Exception and rollback"));
DBHelper.RollbackTransaction();
} Console.ReadLine();
} private static void Transaction2()
{
try
{
DBHelper.BeginTransaction();
//update model
DBHelper.ExecuteNonQuery(CommandType.Text, "UPDATE TRole SET RoleName='Marketer' WHERE ID='R1'");
//throw new Exception(""); DbParameter param = DBHelper.CreateInDbParameter("@ID", DbType.String, "R1");
DbDataReader reader= DBHelper.ExecuteReader(CommandType.Text, "SELECT * FROM TRole WHERE ID=@ID",param);
while (reader.Read())
{
Console.WriteLine(reader["RoleName"]);
} reader.Close(); DBHelper.CommitTransaction();
}
catch(Exception ex)
{
Console.WriteLine(string.Format("Exception and rollback: {0}", ex.Message));
DBHelper.RollbackTransaction();
throw;
}
}
2.2.1
当为嵌套事务时,首次调用BeginTransaction,同样会创建新的TransConnection对象,深度默认为0,并保存在TransConnectionObj字段上;
第n(n>1)次调用时方法时,仅会累加嵌套的深度,不会开起新的事务。
public static void BeginTransaction()
{
if (TransConnectionObj == null)
{
DbConnection conn = DBClient.GetDbConnection(ConnectionString);
OpenConn(conn);
DbTransaction trans = conn.BeginTransaction();
TransConnectionObj = new TransConnection();
TransConnectionObj.DBTransaction = trans;
}
else
{
TransConnectionObj.Deeps += ;
}
}
2.2.2
当CommitTransaction提交事务时,如果深度Deeps>0,那么表示此次提交的事务是内层事务,计数器减1即可;
当调用CommitTransaction提交事务,如果深度为0时,表示为最外层事务,刚做实际上的提交事务工作;
public static void CommitTransaction()
{
if (TransConnectionObj == null) return;
if (TransConnectionObj.Deeps > )
{
TransConnectionObj.Deeps -= ;
}
else
{
TransConnectionObj.DBTransaction.Commit();
ReleaseTransaction();
}
}
2.2.3
当RollbackTransaction提交事务时,如果深度Deeps>0,那么表示此次提交的事务是内层事务,计数器减1即可;
当调用RollbackTransaction提交事务,如果深度为0时,表示为最外层事务,刚做实际上的回滚操作;
public static void RollbackTransaction()
{
if (TransConnectionObj == null) return;
if (TransConnectionObj.Deeps > )
{
TransConnectionObj.Deeps -= ;
}
else
{
TransConnectionObj.DBTransaction.Rollback();
ReleaseTransaction();
}
}
3 变更数据库
同一个底层库,应用到不同项目时,数据库可能会不同。如果我们比较下不同数据库操作类之间的不同点,我们会发现所有的方法都是一致的,就是某些类型不同,如下表所示:
基类 |
SQL Server |
MySql |
DbConnection |
SqlConnection |
MySqlConnection |
DbCommand |
SqlCommand |
MySqlCommand |
DbDataAdapter |
SqlDataAdapter |
MySqlDataAdapte |
DbParameter |
SqlParameter |
MySqlParameter |
所以,根据子类出现的地方,可以用父类替换的原则,将SqlHeper中关于特定数据库的类,换成基类,并将创建特定数据库对象实例的代码统一到IDBClinet中
主要类有
DBHelper: 使用基类访问数据库,并聚合IDBClient来创建特定数据库对象的实例。
IDBClient: 定义创建特定数据库实例的接口,并转成基类型;
SqlServerClient:定义创建SqlServer对象的实例,并转成基类型;
MySqlCient:定义创建MySql对象的实例,并转成基类型;
DBClientFactory:根据类名动态创建IDBClient的实现类;
最后如果想要更换数据库时,只需要修改如下代码,并在配置文件中修改下连接字符串和具体的DBClient的类名:
<appSettings>
<add key="DBConnectionString" value="Data Source=.;Initial Catalog=ProjectData;Persist Security Info=True;User ID=sa;Password=kjkj,911;"/>
<add key="DBClient" value="SqlServerClient"/>
</appSettings>
4 支持数据分页
为了支持数据分页,在DBHelper添加了两个方法,分别返回DataTable和DbDataReader, DbDataReader用于在ORM中转成实体对象。
#region ExecutePaging
public static DataTable ExecutePagingDataTable(CommandType cmdType, string cmdText,int pageIndex,int pageSize,string orderInfo, params DbParameter[] parameterValues)
{
cmdText = DBClient.GetPagingSql(cmdText, pageIndex, pageSize, orderInfo);
return ExecuteDataTable(CommandType.Text, cmdText, parameterValues);
} public static DbDataReader ExecutePagingReader(CommandType cmdType, string cmdText, int pageIndex, int pageSize, string orderInfo, params DbParameter[] parameterValues)
{
cmdText = DBClient.GetPagingSql(cmdText, pageIndex, pageSize, orderInfo);
return ExecuteReader(CommandType.Text, cmdText, parameterValues);
}
#endregion
在分页时,虽然各种数据库的分页方法不一样,但它们都需要信息是:排序字段,开始索引位置,页大小,结束索引位置(可以通过开始索引位置和页大小计算出来)。至于它们最终分页的SQL不一样,可以放在实现了IDBClient的类中。
比如在SqlServerDBClient是用ROW_NUMBER做的:
public string GetPagingSql(string cmdText, int pageIndex, int pageSize, string orderInfo)
{
int startIndex = (pageIndex - ) * pageSize;
int endIndex = startIndex + pageSize + ;
cmdText = string.Format(@";WITH T1 AS({0}),T2 AS(SELECT *,ROW_NUMBER()OVER ({1}) AS _RowNum FROM T1)
SELECT *FROM T2
WHERE _RowNum>{2} AND _RowNum<{3}",cmdText,orderInfo,startIndex,endIndex);
return cmdText;
}
在MySqlDBClient中是用Limit 实现的:
public string GetPagingSql(string cmdText, int pageIndex, int pageSize, string orderInfo)
{
int startIndex = (pageIndex - ) * pageSize;
cmdText = string.Format(@"{0} {1} Limit {2}, {3}", cmdText, orderInfo, startIndex,pageSize);
return cmdText;
}
在下一次随笔中,将会用这个数据库操作类,以及上篇文章用T4 Template生成代码来实现一个简单的ORM框架,支持CRUD。暂时不考虑用反射来实现这个ORM,暂时还hold不住反射的性能问题。
Normal
0
7.8 磅
0
2
false
false
false
EN-US
ZH-CN
X-NONE
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:普通表格;
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-priority:99;
mso-style-parent:"";
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin:0cm;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.5pt;
mso-bidi-font-size:11.0pt;
font-family:"Calibri","sans-serif";
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:"Times New Roman";
mso-bidi-theme-font:minor-bidi;
mso-font-kerning:1.0pt;}
DBHelper (支持事务与数据库变更)的更多相关文章
- DBHelper (支持事务与数据库变更) z
using System; using System.Data; using System.Data.Common; using Project.BaseFramework; using System ...
- ADO.NET中使用事务进行数据库读写的办法
使用事务一般是进行数据写入,数据读取一般是不需要这货的 第一种办法: 使用存储过程: 顾名思义,在存储过程中定义好变量,定义好事务开始,结束,错误回滚然后在ADO.NET中正常调用存储过程的方法就行 ...
- JDBC(二)之JDBC处理CLOB和BLOB及事务与数据库元数据获取
前面大概介绍了JDBC连接数据库的过程,以及怎么操作数据库,今天给大家分享JDBC怎么处理CLOB和BLOB存储图片的事情,以及JDBC怎么去处理事务.怎么在插入数据的时候生成主键返回值 一.JDBC ...
- 这么小的key-val数据库居然也支持事务——与短跑名将同名的数据库Bolt
传送门: 柏链项目学院 什么是Bolt? Bolt是一个纯净的基于go语言编写的key-val数据库,该项目受到LMDB项目的启发,目标是提供一个不需要完整服务器的简单.快速.可靠的数据库. ...
- 尚硅谷面试第一季-08Spring支持的常用数据库事务传播属性和事务隔离级别
目录结构: 关键代码: BookShopServiceImpl.java package Spring支持的常用数据库事务传播属性和事务隔离级别.tx.service.impl; import Spr ...
- JDBC核心技术(获取数据库链接、数据库事务、数据库链接池)
@ 目录 前言 数据的持久化 Java数据存储技术 JDBC介绍 JDBC体系结构 获取数据库链接 Driver接口 加载注册JDBC驱动 获取数据库链接 数据库链接方式(实例) 方式一:代码中显示出 ...
- MySql不支持事务解决
用的是一个绿色版的mysql数据库,发现不支持事务,在网络上搜集资料找到解决方案: 1.执行语句 SHOW ENGINES; 如果发现InnoDB全部显示为“YES”,说明该版本的数据库支持事务 2 ...
- 遇过的坑(2)—MyISAM表类型不支持事务操作
最近需要通过JDBC对数据库做事务型操作,实践时发现,并没有达到想要的效果,表现在:1.每次执行executeUpdate()后,数据就马上能在DB中查到.但按理来说,我还没执行commit(),DB ...
- 第三章(附)mysql表类型MyISAM和InnoDB区别(决定了是否支持事务)
mysql表类型MyISAM和InnoDB区别 MyISAM:这个是默认类型,它是基于传统的ISAM类型,ISAM是Indexed Sequential Access Method (有索引的顺序访问 ...
随机推荐
- Javascript快速入门(下篇)
Javascript, cheer up. Ajax:其通过在Web页面与服务器之间建立一个额外的处理层,这个处理层就被称为Ajax引擎,它解释来自用户的请求,在后台以异步的方式处理服务器通信,其结构 ...
- 【技巧】只利用 Visual Stdio 自带的工具这么找父类?
很多人说只能 F12 看见子类 其实vs里面有一个叫“对象浏览器” 通过这个就可以直接定位父类,不需要利用reflector之类的工具来找父类 具体如下:
- 深入理解CSS计数器
× 目录 [1]创建计数器 [2]使用计数器 [3]DEMO 前面的话 我们对计数器已经不陌生了,有序列表中的列表项标志就是计数器. 创建计数器 创建计数器的基础包括两个方面,一是能重置计数器的起点, ...
- 轻松自动化---selenium-webdriver(python) (十)
本节重点 处理下拉框 switch_to_alert() accept() 下拉框是我们最常见的一种页面元素,对于一般的元素,我们只需要一次就定位,但下拉框里的内容需要进行两次定位,先定位到下拉框,再 ...
- windows环境下跑hadoop自带的wordcount遇到的问题
hadoop环境自己之前也接触过,搭建的是一个伪分布的环境,主从节点都在我自己的机子上,即127.0.0.1,当初记得步骤很多很麻烦的样子(可能自己用ubuntu还不够熟练),包括myeclipse. ...
- Jeet – 先进,直观,灵活的 CSS 网格系统
Jeet 是一个先进的,直观的 CSS 网格系统.通过使用预处理器的强大功能,我们现在可以通过实际分数(或者浮点数)来生成一个基于百分比宽度和间隔的网格.让你用更少的代码,更快的速度构建页面布局. 您 ...
- [Azure附录]1.在Windows Server 2012中安装Active Directory域服务
<Windows Azure Platform 系列文章目录> 1.登陆Windows Server 2012,打开服务器管理器,选择"添加角色和功能" 2.在&quo ...
- [logstash-input-http] 插件使用详解
插件介绍 Http插件是2.0版本才出现的新插件,1.x是没有这个插件的.这个插件可以帮助logstash接收其他主机或者本机发送的http报文. 插件的原理很简单,它自己启动了一个ruby的服务器, ...
- golang内存分配
golang内存分配 new一个对象的时候,入口函数是malloc.go中的newobject函数 func newobject(typ *_type) unsafe.Pointer { flags ...
- 实现iOS图片等资源文件的热更新化(二):自定义的动态 imageNamed
这篇文章,要解决的是,使用一个自定义的 imageNamed 函数来替代系统的 imageNamed 函数.内部逻辑,将贯穿对比论证 关于"合适"的图片的定义.对iOS加载图片的规 ...