169it科技资讯


当前位置:  互联网>综合
本页文章导读:
    ▪不允许启动新事务,因为有其他线程正在该会话中运行(ef并发错误处理)      最近项目上线试运行过程中,总是遇到各种莫名其妙的问题,纠结了很久,今天就ef出现的“不允许启动新事务,因为有其他线程正在该会话中运行”这个错误,记录自己的解决方法。 当遇......
    ▪getting start with storm 翻译 第六章 part-3      转载请注明出处:http://blog.csdn.net/lonelytrooper/article/details/9979019 ProductCategoriesCounterBolt ProductCategoriesCounterBolt类负责记录所有的产品-分类关系。它接收由UsersHistoryBolt发射的产品-分类对并更新计......
    ▪递归求排列和组合(无重复和有重复)      给定一个大小为n的数组,输出所有全排列。 1、数组中无重复元素:从前到后,依次将数组中的元素放置在输出数组中,若放完就输出,然后递归的改变元素的位置,直到输出所有的全排列。......

[1]不允许启动新事务,因为有其他线程正在该会话中运行(ef并发错误处理)
    来源: 互联网  发布时间: 2013-10-26

最近项目上线试运行过程中,总是遇到各种莫名其妙的问题,纠结了很久,今天就ef出现的“不允许启动新事务,因为有其他线程正在该会话中运行”这个错误,记录自己的解决方法。


当遇到这个问题的时候,在网上搜了很久,在这里还是要鄙视一下那些转载又不写出处的站长。


问题发现:

开始一直以为是数据库或者服务器的问题,因为用的是虚拟空间,很多设置没有办法改变。后来加入站长统计之后,发现pv量居然在200左右,突然意识到有可能是并发造成的。于是自己写了一段测试代码,该段代码的作用是模拟用户阅读新闻的时候,使新闻的阅读次数加1(只是改变字段的值,而不是新增一条浏览记录再去统计阅读次数)。代码如下:

public partial class WebForm1 : System.Web.UI.Page
    {
        delegate bool MyDelegate(Read info);

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                ReadInfo ri = new ReadInfo ();

                Read rad1 = ri.Get(1);
                rad1.ReadTime += 1;

                Read rad2 = ri.Get(1);
                rad2.ReadTime += 1;

                MyDelegate myDelegate = new MyDelegate(ri.Update);

                myDelegate.BeginInvoke(rad1, null, null);
                myDelegate.BeginInvoke(rad2, null, null);

                Thread.Sleep(300);
            }
        }

    }

    public class ReadInfo
    {
        testEntities mytest = new testEntities();

        public ReadInfo()
        {
            mytest.Read.MergeOption = System.Data.Objects.MergeOption.OverwriteChanges;
            mytest.Read.EnablePlanCaching = false;
        }

        public Read Get(int Id)
        {
            return mytest.Read.SingleOrDefault(c => c.myId == Id);
        }

        public bool Update(Read Info)
        {
            int Result = 0;

            if (mytest.Read.Count(c => c.myId == Info.myId) == 1)
            {
                Thread.Sleep(100);
                Result = mytest.SaveChanges();
            }

            return Result > 0;
        }
    }

F10跟踪代码运行就报以下错误:





于是监控以下代码发现并发产生的时候,第一次是Modified,第二次却是Unchanged,所以当运行第二次更新的时候,则报错“不允许启动新事务,因为有其他线程正在该会话中运行”





所以最后解决此问题的方法就是将Update的代码改成:


public bool Update(Read Info)
        {
            int Result = 0;

            if (mytest.Read.Count(c => c.myId == Info.myId) == 1)
            {
                if (Info.EntityState == System.Data.EntityState.Modified)
                {
                    mytest.Refresh(RefreshMode.ClientWins, Info);
                    Thread.Sleep(100);
                    Result = mytest.SaveChanges();
                }
            }

            return Result > 0;
        }



虽然这样解决可以保证程序的稳定性,但是当并发发生的时候,阅读次数就不能+1了。不过阅读次数这个属性对于网站的数据而言并不是很重要,所以先这么解决着吧。如果是比较重要的属性,建议还是通过add方法去增加记录,而不是修改记录。或者通过用存储过程,将数据重新刷进表中,但是这样就缺乏实时性。


真是蛋痛的并发!以后再想想,看看有没有其他的解决办法吧。




作者:lilinjian2001 发表于2013-8-14 10:35:35 原文链接
阅读:63 评论:1 查看评论

    
[2]getting start with storm 翻译 第六章 part-3
    来源: 互联网  发布时间: 2013-10-26
转载请注明出处:http://blog.csdn.net/lonelytrooper/article/details/9979019 ProductCategoriesCounterBolt

ProductCategoriesCounterBolt类负责记录所有的产品-分类关系。它接收由UsersHistoryBolt发射的产品-分类对并更新计数器。

每个产品-分类对的事件信息被存放在Redis服务器。出于性能的原因,使用一个本地的用于读的缓存和一个写缓存。事件信息被通过一个后台进程发送到Redis。

对于输入,该bolt也会发送一个包含了更新的计数器的元组来供topology中下一个bolt消费,NewsNotifierBolt,它用于广播消息到最终用户来用于实时更新。

public class ProductCategoriesCounterBoltextendsBaseRichBolt{

...

@Override

public voidexecute(Tuple input) {

String product =input.getString(0);

String categ =input.getString(1);

int total=count(product,categ);

collector.emit(newValues(product,categ,total));

}

...

private intcount(String product,String categ) {

int count=getProductCategoryCount(categ,product);

count ++;

storeProductCategoryCount(categ,product,count);

return count;

}

...

}

该bolt中的持久化被隐藏在getProductCategoryCount和storeProductCategoryCount方法中。我们进一步看下:

package storm.analytics;

...

public class ProductCategoriesCounterBoltextendsBaseRichBolt{

// ITEM:CATEGORY -> COUNT

HashMap<String,Integer>counter=newHashMap<String,Integer>();

// ITEM:CATEGORY -> COUNT

HashMap<String,Integer>pendingToSave=newHashMap<String,Integer>();

...

public intgetProductCategoryCount(Stringcateg,Stringproduct) {

Integer count =counter.get(buildLocalKey(categ,product));

if(count==null) {

String sCount =jedis.hget(buildRedisKey(product),categ);

if(sCount==null||"nil".equals(sCount)){

count =0;

} else{

count =Integer.valueOf(sCount);

}

}

return

    
[3]递归求排列和组合(无重复和有重复)
    来源: 互联网  发布时间: 2013-10-26

给定一个大小为n的数组,输出所有全排列。

1、数组中无重复元素:从前到后,依次将数组中的元素放置在输出数组中,若放完就输出,然后递归的改变元素的位置,直到输出所有的全排列。递归中使用一个标记数组来记录某个元素是否已经被放置过。

2、数组中有重复元素:这个和1比较类似,区别在于用一个标记数组记录某个元素的次数,每放置一次就减一。

问题1的代码如下:

void PermRecur(vector<int>& ivec, vector<int>& use, vector<int>& res, int k)
{
	//如果下标k等于size,说明所有元素已经放置完毕
	if (k == ivec.size())
	{
		for (int i = 0; i < k; ++i)
			cout << res[i] << ' ';
		cout << endl;
		return;
	}
	for (int i = 0; i < ivec.size(); ++i)
	{
		//标记为0表示没有被放置过
		if (use[i] == 0)
		{
			//元素被放置后将标记赋为1
			use[i] = 1;
			res[k] = ivec[i];
			PermRecur(ivec, use, res, k + 1);
			//递归结束后再将该元素的标记赋为0
			use[i] = 0;
		}
	}
}

void Perm(vector<int>& ivec)
{
	int size = ivec.size();
	assert(size > 0);
	//所有元素的标记为初始化为0
	vector<int> use(size);
	vector<int> res(size);
	PermRecur(ivec, use, res, 0);
}
void main()
{
	int a[] = {1, 2, 3};
	vector<int> ivec(a, a + 3);
	Perm(ivec);
}

问题2的代码如下:

#include <iostream>
#include <vector>
#include <assert.h>
using namespace std;

void PermRecur(vector<int>& num, vector<int>& use, vector<int>& res, int k)
{
	//如果下标k等于size,说明所有元素已经放置完毕
	if (k == res.size())
	{
		for (int i = 0; i < k; ++i)
			cout << res[i] << ' ';
		cout << endl;
		return;
	}
	for (int i = 0; i < num.size(); ++i)
	{
		//标记大于0说明还有剩余的元素没有放置
		if (use[i] > 0)
		{
			//元素被放置后次数减1
			--use[i];
			res[k] = num[i];
			PermRecur(num, use, res, k + 1);
			//递归结束后再将该元素的次数加1
			++use[i];
		}
	}
}

void Perm(vector<int>& ivec)
{
	assert(!ivec.empty());
	int size = ivec.size();
	vector<int> res(size);
	vector<int> use;
	vector<int> num;
	//根据ivec统计每个元素的出现次数,并将去重后的所有元素存在num中
	use.push_back(1);
	num.push_back(ivec[0]);
	for (int i = 1; i < size; ++i)
	{
		int j = 0;
		for (; j < i; ++j)
		{
			if (ivec[i] == ivec[j])
			{
				++use[j];
				break;
			}
		}
		if (j == i)
		{
			use.push_back(1);
			num.push_back(ivec[i]);
		}
	}
	PermRecur(num, use, res, 0);
}

void main()
{
	int a[] = {1, 2, 2};
	vector<int> ivec(a, a + 3);
	Perm(ivec);
}

给定一个大小为n的数组,输出所有的子集。子问题是从n个元素中选择m个元素,然后循环调用即可。

1、数组中无重复的元素:从前到后依次将数组中的元素放置到输出数组中,当元素个数达到m时输出即可。然后进行递归,将剩余的元素和m个元素进行交换。

2、数组中有重复的元素:和全排列类似,先去重并计算元素的次数,然后进行递归。

问题1的代码如下:

#include <iostream>
#include <vector>
#include <assert.h>
using namespace std;

void CombRecur(vector<int>& ivec, vector<int>& res, int m, int begin, int k)
{
	//当k等于m的时候输出结果
	if (k == m)
	{
		for (int i = 0; i < res.size(); ++i)
			cout << res[i] << ' ';
		cout << endl;
		return;
	}
	for (int i = begin; i < ivec.size(); ++i)
	{
		res[k] = ivec[i];
		CombRecur(ivec, res, m, i + 1, k + 1);
	}
}

void Comb(vector<int>& ivec)
{
	assert(!ivec.empty());
	for (int i = 1; i <= ivec.size(); ++i)
	{
		vector<int> res(i);
		CombRecur(ivec, res, i, 0, 0);
	}
}

void main()
{
	int a[] = {1, 2, 3};
	vector<int> ivec(a, a + 3);
	Comb(ivec);
}

问题2的代码如下:

#include <iostream>
#include <vector>
#include <assert.h>
using namespace std;

void CombRecur(vector<int>& num, vector<int>& use, vector<int>& res, 
			   int m, int begin, int k)
{
	//当k等于m时,说明已经选够m个元素
	if (k == m)
	{
		for (int i = 0; i < res.size(); ++i)
			cout << res[i] << ' ';
		cout << endl;
		return;
	}
	for (int i = begin; i < num.size(); ++i)
	{
		//如果元素次数大于0就选择
		if (use[i] > 0)
		{
			//选择之后就将元素次数减1
			--use[i];
			res[k] = num[i];
			//这里递归的时候begin仍然是i,因为第i个元素有可能重复
			CombRecur(num, use, res, m, i, k + 1);
			++use[i];
		}
	}
}

void Comb(vector<int>& ivec)
{
	assert(!ivec.empty());
	int size = ivec.size();
	vector<int> num;
	vector<int> use;
	//根据ivec统计每个元素的出现次数,并将去重后的所有元素存在num中
	num.push_back(ivec[0]);
	use.push_back(1);
	for (int i = 1; i < size; ++i)
	{
		int j = 0;
		for (; j < i; ++j)
		{
			if (ivec[i] == ivec[j])
			{
				++use[j];
				break;
			}
		}
		if (j == i)
		{
			use.push_back(1);
			num.push_back(ivec[i]);
		}
	}
	//从1~n循环调用即可求出大小为1~n的所有子集
	for (int i = 1; i <= size; ++i)
	{
		vector<int> res(i);
		CombRecur(num, use, res, i, 0, 0);
	}
}

void main()
{
	int a[] = {1, 2, 2};
	vector<int> ivec(a, a + 3);
	Comb(ivec);
}


作者:f_x_q 发表于2013-8-15 9:17:47 原文链接
阅读:49 评论:0 查看评论

    
最新技术文章:
▪用户及权限基础 2---- Linux权限    ▪用户及权限基础 3---- Linux扩展权限    ▪git 简明教程(1) --创建及提交
▪背包 代码    ▪json对象的封装与解析    ▪01背包,完全背包,多重背包 ,模板代码
▪apache安装详解    ▪HDU 4668 Finding string (解析字符串 + KMP)    ▪《TCP-IP详解 卷1:协议》学习笔记(二)
▪《TCP-IP详解 卷1:协议》学习笔记(持续更新    ▪windows下使用swig    ▪gensim试用
▪Linux Shell脚本编程--nc命令使用详解    ▪solr对跨服务器表联合查询的配置    ▪递归和非递归实现链表反转
▪Linux磁盘及文件系统管理 1---- 磁盘基本概念    ▪Cholesky Decomposition    ▪HTTP协议学习
▪用C语言写CGI入门教程    ▪用hdfs存储海量的视频数据的设计思路    ▪java多线程下载的实现示例
▪【原创】eAccelerator 一个锁bug问题跟踪    ▪hadoop学习之ZooKeeper    ▪使用cuzysdk web API 实现购物导航类网站
▪二维数组中的最长递减子序列    ▪内嵌W5100的网络模块WIZ812MJ--数据手册    ▪xss 跨站脚本攻击
▪RobotFramework+Selenium2环境搭建与入门实例    ▪什么是API    ▪用PersonalRank实现基于图的推荐算法
▪Logtype    ▪关于端口号你知道多少!    ▪Linux基本操作 1-----命令行BASH的基本操作
▪CI8.7--硬币组合问题    ▪Ruby on Rails 学习(五)    ▪如何使用W5300实现ADSL连接(二)
▪不允许启动新事务,因为有其他线程正在该会    ▪getting start with storm 翻译 第六章 part-3    ▪递归求排列和组合(无重复和有重复)
▪工具类之二:RegexpUtils    ▪Coding Interview 8.2    ▪Coding Interview 8.5
▪素因子分解 Prime factorization    ▪C# DllImport的用法    ▪图的相关算法
▪Softmax算法:逻辑回归的扩展    ▪最小生成树---Kruskal算法---挑战程序设计竞赛    ▪J2EE struts2 登录验证
▪任意两点间的最短路径---floyd_warshall算法    ▪Sqoop实现关系型数据库到hive的数据传输    ▪FFMPEG采集摄像头数据并切片为iPhone的HTTP Stream
▪Ubuntu 13.04 – Install Jetty 9    ▪TCP/IP笔记之多播与广播    ▪keytool+tomcat配置HTTPS双向证书认证
▪安装phantomjs    ▪Page Redirect Speed Test    ▪windows media player 中播放pls的方法
▪sre_constants.error: unbalanced parenthesis    ▪http headers    ▪Google MapReduce中文版
▪The TCP three-way handshake (connect)/four wave (closed)    ▪网站反爬虫    ▪Log4j实现对Java日志的配置全攻略
▪Bit Map解析    ▪Notepad 快捷键 大全    ▪Eclipse 快捷键技巧 + 重构
▪win7 打开防火墙端口    ▪Linux Shell脚本入门--awk命令详解    ▪Linux Shell脚本入门--Uniq命令
▪Linux(Android NDK)如何避免僵死进程    ▪http Content-Type一览表    ▪Redis实战之征服 Redis + Jedis + Spring (二)
▪Tomcat7.0.40 基于DataSourceRealm的和JDBCRealm的资源    ▪利用SQOOP将ORACLE到HDFS    ▪django输出 hello world
▪python re    ▪unity3D与网页的交互    ▪内存共享基本演示
▪python join    ▪不再为无限级树结构烦恼,且看此篇    ▪python实现变参
▪打开文件数限制功能不断地制造问题    ▪Arduino Due, Maple and Teensy3.0 的 W5200性能测试    ▪Selenium实例----12306网站测试
▪基于协同过滤的推荐引擎    ▪C4.5决策树    ▪C#HTTP代理的实现之注册表实现
▪nosql和关系型数据库比较?    ▪如何快速比较这两个字符串是否相等?    ▪hdoj 1863 畅通工程 最小生成树---prime算法
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2017,169IT.COM,E-mail:www_169it_com#163.com(请将#改为@)

浙ICP备11055608号