之前做mysql事务测试的时候都是在mysql服务端存储过程里面包含事务。

例如:

CREATE DEFINER=`root`@`localhost` PROCEDURE `Test`(out debitb decimal(14,2))
BEGIN

-- SET TRANSACTION ISOLATION LEVEL Serializable ;
START TRANSACTION ;

select @db:=debit_balance from c_account_customer where id=1 for update;
set debitb=@db;
insert into abacus.testvalue (val) values (@db);
-- select sleep(1); -- 模拟耗时
insert into abacus.c_entry_customer (customer_id,item_id,ref_id,direction,amount,operation,operation_id,note) values (1,1,1,1,1,1,1,1);
insert into abacus.c_entry_customer (customer_id,item_id,ref_id,direction,amount,operation,operation_id,note) values (1,2,1,1,1,1,1,1);
update abacus.c_account_customer set debit_balance=@db+1 where id=1;
commit;

END

这样的话并发测试等都有良好的表现,参考:mysql 并发测试

今天早上想用我们客户端封装的事务方法进行同样的测试:

如下:

public static void Execution1(object i)
{
Transaction ts = new Transaction();
ts.AppendBack("debit_balance","select debit_balance from c_account_customer where id=1 for update;");
ts.Append(" insert into abacus.testvalue (val) values ({0});", new TransactionReplaceArg("debit_balance"));
ts.Append(" insert into abacus.c_entry_customer (customer_id,item_id,ref_id,direction,amount,operation,operation_id,note) values (1,1,1,1,1,1,1,1);");
ts.Append(" insert into abacus.c_entry_customer (customer_id,item_id,ref_id,direction,amount,operation,operation_id,note) values (1,2,1,1,1,1,1,1);");
ts.Append(" update abacus.c_account_customer set debit_balance={0}+1 where id=1;", new TransactionReplaceArg("debit_balance"));

DbAccess.dataAcces.ExecuteEntire(ts);
var a = (Decimal)ts.ReadBack("debit_balance");
Task.Factory.StartNew(() => Logs.jobStatus.Info("更新前值:" + a+ ";当前线程id:" + Thread.CurrentThread.ManagedThreadId + ";循环:" + (int)i));

}

可是测试结果出乎了我的的预料:

1,首先,调用我们自己封装的事务方法进行并发测试,10个并发,持续5分钟。(可参考:mysql 并发测试),往常这都是小儿科,可是没几秒竟然报错了,如下图

2,难道我们自己封装的事务方法性能太差

2.1  先调用我们封装的事务方法循环100次。耗时1秒。

2.2  调用mysql 服务端包含事务的存储过程循环100次。耗时1秒。

2.3  调用我们封装的事务方法循环10000次。耗时50秒。

2.4  调用mysql 服务端包含事务的存储过程循环10000次。耗时18秒。

看来,我们自己写的事务方法性能的确比较慢。

3, 调用存储过程中的事务并发测试,,10个并发,持续5分钟。(可参考:mysql 并发测试),如下图:

目前最大表4000W多条数据,5分钟,插入数据10*102095*2

补充:昨天对我们客户端封装的事务方法进行了分析,结果是比服务端的事务慢。

为了验证到底是mysql客户端的原因?还是我们封装的有问题?那我在mysql事务中直接写sql语句——哥们我不封装了。

代码如下:

public decimal TransactionTest()
{
decimal v = 0;
using (MySqlConnection con = new MySqlConnection(connectionString))
{
con.Open();
using (MySqlTransaction trans = con.BeginTransaction())
{
try
{
using (MySqlCommand cmd = new MySqlCommand("select debit_balance from c_account_customer where id=1 for update;", con, trans))
{
v = (decimal)cmd.ExecuteScalar();
}
using (MySqlCommand cmd = new MySqlCommand("insert into abacus.testvalue (val) values (@db);", con, trans))
{
cmd.Parameters.AddWithValue("@db", v);
cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
}
using (MySqlCommand cmd = new MySqlCommand(" insert into abacus.c_entry_customer(customer_id, item_id, ref_id, direction, amount, operation, operation_id, note) values(1, 1, 1, 1, 1, 1, 1, 1); ", con, trans))
{
cmd.ExecuteNonQuery();
}
using (MySqlCommand cmd = new MySqlCommand(" insert into abacus.c_entry_customer(customer_id,item_id,ref_id,direction,amount,operation,operation_id,note) values (1,2,1,1,1,1,1,1);", con, trans))
{
cmd.ExecuteNonQuery();
}
using (MySqlCommand cmd = new MySqlCommand("update abacus.c_account_customer set debit_balance=@db+1 where id=1;", con, trans))
{
cmd.Parameters.AddWithValue("@db", v);
cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
}
trans.Commit();
}
catch (Exception ex)
{
trans.Rollback();
}
finally
{
con.Close();
}
return v;
}
}
}

测试结果:

1.

  循环10000次                               开始时间                                                      结束时间                          耗时(秒)

直接调用mysql客户端事务,        2015-08-27 08:30:03                                 2015-08-27 08:31:10       67

客户端封装的事务方法                 2015-08-27 08:50:33                                 2015-08-27 08:51:39       66

mysql服务端事务                         2015-08-27 08:57:47                                 2015-08-27 08:58:16        29

2 . 直接调用mysql客户端事务,10个并发,持续5分钟。几秒后报错

总结: 我们自带的事务目前性能比较差,并且在并发的情况下会报错。  

mysql客户端事务性能比较差

补充: 针对早上的出现OutOfMemoryException问题,我打开任务管理器->性能,发现8G内存才用了4G多点。

内存很充分,为什么还是会报OutOfMemoryException错?

查了些资料:

总的来说OutOfMemoryException会在两种情况下发生,

1 .进程虚拟内存空间耗尽

 2 .系统物理内存耗尽

第2种状况显然不是。

那么我们在看看第一种解释:

32位操作系统可以寻址4GB的地址空间,如果系统没有打开3GB开关的话,其中2GB分配给操作系统内核,另外2GB分配给用户程序。内核的2GB空间被所有的进程,操作系统所共享。但用户模式的那2GB空间为每个进程独享

针对第一种问题,我本机刚好是4G左右出现OutOfMemoryException。可是我是64位操作系统?

我继续查资料:

又有这么一说:为了更好使用内存,你最好编译代码为64位的。

哎,这是个问题,因为vs2013默认活动解决方案平台是 any cpu,要不改成x64试试。

改成x64后,OutOfMemoryException 问题不见了,本机内存也升到5G以上了。

如下图:

后续问题

如果你以为以上问题就完美解决了mysql并发报错? 肯定没这么简单。

因为后续出现了,timeout错误。

针对以上问题我又进行了分析.

回顾:

mysql服务器最大链接1024 。

C#  客户端最大连接数500.

经过折腾,当内存足够使用, 我们并发足够大的时候,500个连接数肯定不够用,有很多链接需要等待,CommandTimeout默认貌似30秒,等待时间长了肯定会超时。

问题又来了? 那我把CommandTimeout设为等于0 ,不就没时间限制了吗?

这样的话,链接数越积越多,系统肯定崩溃。

那么把mysql服务器和客户端最大连接数改为更大比如10000(mysql服务端最大支持16000+)如何?

这么mysql服务器不就奔溃了嘛。

总结:我们应该根据mysql 服务器连接数,客户端连接数,事务处理响应速度合理,并发级别合理规划mysql服务器和应用程序服务器,当然代码也要写的漂亮。

参考链接: http://stackoverflow.com/questions/14186256/net-out-of-memory-exception-used-1-3gb-but-have-16gb-installed

如果我的思路不对请指正,大家也可以测测。

mysql 服务端事务和客户端事务对比分析的更多相关文章

  1. MySQL服务端恶意读取客户端文件漏洞 (DDCTF2019和国赛均涉及到这个漏洞)

    mysql协议中流程和go语言实现的恶意mysql服务器:https://blog.csdn.net/ls1120704214/article/details/88174003 poc :https: ...

  2. “快的打车”创始人陈伟星的新项目招人啦,高薪急招Java服务端/Android/Ios 客户端研发工程师/ mysql DBA/ app市场推广专家,欢迎大家加入我们的团队! - V2EX

    "快的打车"创始人陈伟星的新项目招人啦,高薪急招Java服务端/Android/Ios 客户端研发工程师/ mysql DBA/ app市场推广专家,欢迎大家加入我们的团队! - ...

  3. windows10 64位 安装mysql服务端 并使用navicat客户端链接 掉的一堆坑

    1.目的 安装mysql服务端 并使用navicat客户端链接 2.过程 1)下载mysql服务端 下载过程(参考https://blog.csdn.net/youxianzide/article/d ...

  4. mysql服务端安装的系列问题处理

    1.mysql服务无法启动,报1067错误 注意:mysql服务端加压之后的文件名最好不要带其他符号(如:"_"之类等其他的一些符号),用纯英文跟数字就可以,没有经过仔细验证带符号 ...

  5. Delphi XE5通过WebService开发Web服务端和手机客户端

    Delphi XE5通过WebService开发Web服务端和手机客户端介绍 我们开发一个三层的android程序 建立一个webservices  stand-alone vcl applicati ...

  6. [发布]SuperIO v2.2.5 集成OPC服务端和OPC客户端

    SuperIO 下载:本站下载 百度网盘 1.修复串口号大于等于10的时候导致IO未知状态. 2.优化RunIODevice(io)函数内部处理流程,二次开发可以重载这个接口. 3.优化IO接收数据, ...

  7. SVN--下载、安装VisualSVN server 服务端和 TortoiseSVN客户端

    前言: 在http://www.cnblogs.com/xiaobaihome/archive/2012/03/20/2407610.html的博客中已经很详细地介绍了SVN的服务器--VisualS ...

  8. 使用rsync在windows(服务端)与linux(客户端)之间同步

    说明: 1.cwRsyncServer服务端 系统:Windows7 IP地址:192.168.0.110 2.Rsync客户端 系统:CentOS 6.7 IP地址:192.168.0.141 实现 ...

  9. Spring Cloud 服务端注册与客户端调用

    Spring Cloud 服务端注册与客户端调用 上一篇中,我们已经把Spring Cloud的服务注册中心Eureka搭建起来了,这一章,我们讲解如何将服务注册到Eureka,以及客户端如何调用服务 ...

随机推荐

  1. Mr. Frog’s Game(模拟连连看)

    Description One day, Mr. Frog is playing Link Game (Lian Lian Kan in Chinese). In this game, if you ...

  2. Huffuman树

    问题描述 Huffman树在编码中有着广泛的应用.在这里,我们只关心Huffman树的构造过程. 给出一列数{pi}={p0, p1, …, pn-1},用这列数构造Huffman树的过程如下: 1. ...

  3. About Dynamic Programming

    Main Point: Dynamic Programming = Divide + Remember + Guess 1. Divide the key is to find the subprob ...

  4. Internet History,Tecchnology and Security

    Internet History Internet Technologe Internet Secure

  5. JAVA mysql数据库 配置

    mysql 版本 5.7 数据库连接版本 <!--MySql--><dependency> <groupId>mysql</groupId> <a ...

  6. TCP系列21—重传—11、TLP

    一.介绍 Tail Loss Probe (TLP)是同样是一个发送端算法,主要目的是使用快速重传取代RTO超时重传来处理尾包丢失场景.在一些WEB业务中,如果TCP尾包丢失,如果依靠RTO超时进行重 ...

  7. oracle 删除数据恢复

    select *  from taxi_comp_worksheet_ext   as of timestamp to_timestamp('2014-09-22 13:00:00', 'yyyy-m ...

  8. python 爬虫每天定时启动爬虫任务

     # coding=utf-8 import datetime import time def doSth(): # 这里是执行爬虫的main程序     print '爬虫要开始运转了....'   ...

  9. C语言100例02 PHP版(练习)

    问题: 企业发放的奖金根据利润提成. 利润(I)低于或等于10万元时,奖金可提10%: 利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可提成7.5%: 20万到 ...

  10. 【问题解决】Project facet Java version 1.7 (或者1.8)is not supported.

    在移植eclipse项目时,如果遇到 “Project facet Java version 1.7 is not supported.” 项目中的jdk1.7不支持.说明项目是其他版本jdk编译的, ...