[转载]Android应用全屏的方法

mikel阅读(1199)

[转载]Android应用全屏的方法 – – 博客园.

一般Android的应用启动时都有欢迎界面,类似QQHD启动那样。比较大方绚丽。心动不如行动,有时间自己也来实现类似的效果,嘿嘿。QQ2011

观察发现QQHD的欢迎界面是全屏的,这个好办。下面就Android应用调用全屏方式说明一下。

一般使Android程序的画面充满整个屏幕,有两种方法。

1.直接代码编写

1 @Override
2     protected void onCreate(Bundle savedInstanceState)
3     {
4         requestWindowFeature(Window.FEATURE_NO_TITLE);
5 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
6         super.onCreate(savedInstanceState);
7         setContentView(R.layout.welcome);
8     }


2.配置AndroidManifest.xml

 1     <application
 2         android:icon="@drawable/ic_launcher"
 3         android:label="@string/app_name" >
 4         <activity
 5             android:name=".Welcome"
 6             android:label="@string/app_name"
 7             android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
 8         >
 9             <intent-filter>
10                 <action android:name="android.intent.action.MAIN" />
11                 <category android:name="android.intent.category.LAUNCHER" />
12             </intent-filter>
13         </activity>
14         <activity
15             android:name=".AboutApp"
16             android:label="@string/aboutapp_title"
17             android:theme="@android:style/Theme.Dialog"
18         />
19     </application>

安卓示例

[转载]sqlserver 行转列

mikel阅读(1017)

[转载]sqlserver 行转列 – 李 鹏 – 博客园.

SQLServer把行转成列在我们编码中是经常遇到的我做一个小例子大家看一下

 1 --创建一个表
 2 create table PayPhoneMoney
 3 (
 4     id int identity(1,1),
 5     userName Nvarchar(20),
 6     payType nvarchar(20),
 7     money   decimal,
 8     payTime datetime,
 9     constraint pk_id primary key(id)
10 )
11 --插入点数据
12 insert into PayPhoneMoney values('小李','支付宝',20,'2012-01-03')
13 insert into PayPhoneMoney values('小陈','工行',20,'2012-01-06')
14 insert into PayPhoneMoney values('小赵','交行',50,'2012-01-06')
15 insert into PayPhoneMoney values('小陈','支付宝',60,'2012-01-06')
16 insert into PayPhoneMoney values('小赵','工行',30,'2012-01-16')
17 insert into PayPhoneMoney values('小张','中行',30,'2012-01-16')
18 insert into PayPhoneMoney values('小李','支付宝',60,'2012-01-16')

看一下表中的数据

我们要想查一下每个人所有支付形式下的总钱数如图所示

1 -- 查一下每个人所有支付形式下的总钱数
2 select userName from PayPhoneMoney group by userName
3 select userName,
4     sum(case payType when '支付宝' then money else 0 end) as 支付宝 ,
5     sum(case payType when '工行' then money else 0 end) as 工行, 
6     sum(case payType when '交行' then money else 0 end) as 交行,
7     sum(case payType when '中行' then money else 0 end) as 中行
8 from PayPhoneMoney 
9 group by userName

–我们这只列出了几种支付方式实际中还有很多支付方式不能一个一个都用case when 吧
–可以这样

1 declare @cmdText varchar(8000)
2 set @cmdText='select userName, '
3 select @cmdText=@cmdText+' sum(case payType when'''+payType+'''Then money else 0 end) as '''+payType
4 +''','+char(10) from (select Distinct payType from PayPhoneMoney) T
5 print @cmdText--发现多一个逗号下面把逗号去掉
6 set @cmdText=left(@cmdText,len(@cmdText)-2)--去掉逗号
7 set @cmdText=@cmdText+'from PayPhoneMoney group by userName'
8 print @cmdText
9 exec(@cmdText)

看一下结果是一样的吧

[转载]asp.net mvc2网站部署在IIS6的方法

mikel阅读(1031)

[转载]asp.net mvc2网站部署在IIS6的方法 – 我思故我在… – 博客园.

部署环境: Server 2003 +IIS6

1.先安装好IIS6,再安装.net framework 4.0和ASP.NET mvc 安装包(主要是里面的一个dll,不安装也可以,只需要找到这个dll,将mvc.dll 放入网站bin目录下,这个dll文件的默认路径是C:\Program Files\Microsoft ASP.NET\ASP.NET MVC 2\Assemblies\System.Web.Mvc.dll)

2.在IIS中新建网站设置web主目录,这个不详细说了,接着说重点

3.在发布的网站上右击【属性】—【主目录】—-【配置】,在弹出的【应用程序配置】窗口中点击【添加】,点击【浏览】将“可执行文件”设置为“C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll”,“扩展名”设置为”.mvc”,取消【确认文件是否存在

然后在下面点击【插入】,同样选择aspnet_isapi.dll,取消【确认文件是否存在】。

在发布的网站上右击【属性】–【APS.NET】,将【ASP.NET version】设置为4.0.30319

4.在【Web服务扩展】中设置ASP.NET v4.0.30319 为允许

以上配置完成后就大功告成了,以上亲测成功,若有问题欢迎留言一起探讨!

PS:若先装的.net framework 4.0,后装的IIS,需要注册aspnet到IIS,方法如下:

注意:要以管理员的身份运行

启动cmd窗口 (win键+R )  ,找到 4.0所在的目录,本人机器目录是
C:\Windows\Microsoft.NET\Framework\v4.0.30319

启动CMD进入上面的目录C:\Windows\Microsoft.NET\Framework\v4.0.30319

运行  aspnet_regiis.exe -i

稍等一会, aspnet_regiis 注册成功

[转载]ActionScript中Event类的几个属性

mikel阅读(1890)

[转载]Event类的几个属性 – 赵杰民 – 博客园.

var mc:MovieClip = new MovieClip();
mc.graphics.beginFill(0x0066cc);
mc.graphics.drawRect(100,100,200,200);
addChild(mc);
mc.addEventListener(MouseEvent.CLICK,onClick);
function onClick(e:MouseEvent):void
{
 trace(e.type)         // Event类下的,表示事件的类型
 trace(e.bubbles)      // Event类下的,指示事件是否为冒泡事件
 trace(e.cancelable)   // Event类下的,表示是否忽视事件的默认行为
}

bubbles  默认false  true 说明可以使用冒泡事件false 说明不可以

cancelable默认false如果不执行默认行为,则此值为 true;否则为 false。它是只读属性如果要修改可以用preventDefault()方法,可以取消默认行为

代码可通过访问 cancelable 属性来检查是否可以阻止任何指定事件对象的默认行为。 cancelable 属性包含一个布尔值,用于指示是否可以阻止默认行为。 您可以使用

preventDefault() 方法阻止或取消与少量事件关联的默认行为。

cancelable 还可以这样理解表示某个事件的默认行为能否被阻止。 true表示可以阻止,false表示不可以。

Event类的eventPhase属性也是只读属性,表示事件流的阶段。1、表示捕获阶段 2、目标阶段 3、冒泡阶段

var sp1:Sprite = new Sprite();
var sp2:Sprite = new Sprite();
this.addChild(sp1);
sp1.addChild(sp2);
drawRect(sp1,0xff9900,200);
drawRect(sp2,0x0000ff,100);
function drawRect(obj:DisplayObject,c:uint,b:uint):void
{
 //  这里要把严谨模式去掉
 obj.graphics.beginFill(c);
 obj.graphics.drawRect(0,0,b,b);
}
sp1.name = "sp1";
sp2.name = "sp2";
//  为所有节点注册事件
//   使用捕获阶段
stage.addEventListener(MouseEvent.CLICK,clickFunc,true);
this.addEventListener(MouseEvent.CLICK,clickFunc,true);
sp1.addEventListener(MouseEvent.CLICK,clickFunc,true);
//   使用目标阶段
sp2.addEventListener(MouseEvent.CLICK,clickFunc);      // sp2属于目标阶段不用设置true
//    冒泡阶段
stage.addEventListener(MouseEvent.CLICK,clickFunc);
this.addEventListener(MouseEvent.CLICK,clickFunc);
sp1.addEventListener(MouseEvent.CLICK,clickFunc);
function clickFunc(e:MouseEvent):void
{
 var s:String = e.currentTarget.name;  // 获得实例名
 if(s)   //  如果存在实例名,那么就输出实例名
 {
  trace(s,"阶段" + e.eventPhase);
 }
 else    //  如果实例名不存在,说明到达舞台,输出stage
 {
  trace("stage","阶段" + e.eventPhase);
 }
}

[转载]Android中文API合集(7)开发者指南合集(2) (chm格式下载)

mikel阅读(1198)

[转载]Android中文API合集(7) + 开发者指南合集(2) (chm格式) – 农民伯伯 – 博客园.

前言

Android中文翻译组是一个非盈利性质的开源组织至今已超过300人报名参与关于翻译组的介绍,请看这里。欢迎更多朋友加入,发邮件到over140@gmail.com申请加入或直接参与Wiki编辑。

Android中文翻译组WIKI网站http://wikidroid.sinaapp.com/不管是否加入我们,请与我们一起自由编辑和分享相关中文资料。

Android中文翻译组官方网站http://androidbox.sinaapp.com/。有在线的中文API、开发者指南、开源项目以及Android视频专栏。

本合集发布日期:2012131,涵盖历次合集内容,最新版请关注翻译组微博:http://weibo.com/android2

截图

下载

本站

结束

由于精力有限,目前暂停了自动更新客户端的维护,内部组织结构还在调整,推荐想参与的朋友直接参与到WIKI编辑。

[转载]解决SWFUpload在Chrome、Firefox等浏览器下的问题

mikel阅读(1833)

[转载]解决SWFUpload在Chrome、Firefox等浏览器下的问题 – 杨中科 – 博客园.

SWFUpload 是一个非常不错的异步上传组件,但是在Chrome、Firefox等浏览器下使用的时候会有问题。问题如下:为了防止跳过上传页面直接向“接受 SWFUpload上传的一般处理程序”(假如是Upload.ashx)发送请求造成WebShell漏洞,我的系统中对于Upload.ashx进行 了权限控制,只有登录用户才能进行上传。在IE下没问题,但是在Chrome下运行报错“用户未登录”。

经过搜索得知:因为SWFUpload是靠Flash进行上传的,Flash在IE下会把当前页面的Cookie发到Upload.ashx,但是Chrome、Firefox下则不会把当前页面的Cookie发到Upload.ashx。因为Session是靠Cookie中保存的SessionId实现的(传智播客的ASP.NET视频教程中讲到了Session和Cookie的关系,对于这点不熟悉的可以参考《传智播客视频教程2011版:ASP.NET≠拖控件》),这样由于当前页面的Cookie不会传递给Flash请求的Upload.ashx,因此请求的文件发送到Upload.ashx就是一个新的Session了,当然这个Session就是没有登录的了。

解决这个问题的思路也很简单,那就是手动把SessionId传递给服务器,再服务器端读出SessionId再加载Session。其实解决问题的办法SWFUpload的Demo中已经给出了,那就是在SWFUpload的构造函数中设置post_params参数:

                swfu = new SWFUpload({
                    // Backend Settings
                    upload_url: "/Upload.ashx",
                    post_params: {
                        "ASPSESSID": "<%=Session.SessionID %>"},
post_params中设定的键值对将会以Form表单的形式传递到Upload.ashx,也就是SWFUpload提供了为请求增加自定义请求参数的接口。
上面的代码把当前页面的SessionId写到ASPSESSID值中,当用户上传文件后,ASPSESSID就会传递到服务器上了,在Global.asax的Application_BeginRequest中添加如下代码:
            var Request = HttpContext.Current.Request;
            var Response = HttpContext.Current.Response;
            /* Fix for the Flash Player Cookie bug in Non-IE browsers.
             * Since Flash Player always sends the IE cookies even in FireFox
             * we have to bypass the cookies by sending the values as part of the POST or GET
             * and overwrite the cookies with the passed in values.
             * 
             * The theory is that at this point (BeginRequest) the cookies have not been read by
             * the Session and Authentication logic and if we update the cookies here we'll get our
             * Session and Authentication restored correctly
             */

            try
            {
                string session_param_name = "ASPSESSID";
                string session_cookie_name = "ASP.NET_SESSIONID";

                if (HttpContext.Current.Request.Form[session_param_name] != null)
                {
                    UpdateCookie(session_cookie_name, HttpContext.Current.Request.Form[session_param_name]);
                }
                else if (HttpContext.Current.Request.QueryString[session_param_name] != null)
                {
                    UpdateCookie(session_cookie_name, HttpContext.Current.Request.QueryString[session_param_name]);
                }
            }
            catch (Exception)
            {
                Response.StatusCode = 500;
                Response.Write("Error Initializing Session");
            }
其中UpdateCookie方法的定义如下:
        static void UpdateCookie(string cookie_name, string cookie_value)
        {
            HttpCookie cookie = HttpContext.Current.Request.Cookies.Get(cookie_name);
            if (cookie == null)
            {
                cookie = new HttpCookie(cookie_name);
                //SWFUpload 的Demo中给的代码有问题,需要加上cookie.Expires 设置才可以
                cookie.Expires = DateTime.Now.AddYears(1);                
                HttpContext.Current.Request.Cookies.Add(cookie);
            }
            cookie.Value = cookie_value;
            HttpContext.Current.Request.Cookies.Set(cookie);
        }

原理:当用户请求到达ASP.NET引擎的时候Application_BeginRequest方法首先被调用,在方法中看客户端是否提交上来了ASPSESSID,如果有的话则把ASPSESSID的值写入Cookie(以”ASP.NET_SESSIONID”为Key,因为ASP.Net中SessionId就是保存在”ASP.NET_SESSIONID”为Key的Cookie中的),Application_BeginRequest方法后就可以从Cookie中读取到”ASP.NET_SESSIONID”的值还原出页面的Session了。

如果网站中还用到了Membership的FormsAuthentication验证,则还需要把AUTHID也按照SessionID的方法进行处理,这一点是其他讲到SWFUpload这个Bug处理的文章中没有提到的。

在SWFUpload的构造函数中设置post_params参数:

                swfu = new SWFUpload({
                    // Backend Settings
                    upload_url: "/AdminHT/UploadArticleImg.ashx",
                    post_params: {
                        "ASPSESSID": "<%=Session.SessionID %>",
                        "AUTHID" : "<%=Request.Cookies[FormsAuthentication.FormsCookieName].Value%>"
                    },
在在Global.asax的Application_BeginRequest中添加如下代码:
            try
            {
                string auth_param_name = "AUTHID";
                string auth_cookie_name = FormsAuthentication.FormsCookieName;

                if (HttpContext.Current.Request.Form[auth_param_name] != null)
                {
                    UpdateCookie(auth_cookie_name, HttpContext.Current.Request.Form[auth_param_name]);
                }
                else if (HttpContext.Current.Request.QueryString[auth_param_name] != null)
                {
                    UpdateCookie(auth_cookie_name, HttpContext.Current.Request.QueryString[auth_param_name]);
                }

            }
            catch (Exception)
            {
                Response.StatusCode = 500;
                Response.Write("Error Initializing Forms Authentication");
            }

[转载]jquery插件制作心得

mikel阅读(983)

[转载]jquery插件制作心得 – 殷海超 – 博客园.

今天刚刚把jquery的插件制作学习了一下,总结一下别人写的和自己的心得,方便其他初学者的学习,考虑到要学习jquery插件制作的人一定知道jquery插件的好处和通用性,这里就不多说
一、先从一个简单的实例,不需要带参数的一个方法开始
//创建一个匿名函数   
(function($){   
    //给jQuery附加一个新的方法(详细见备注1)
   $.fn.extend({    
        //插件的名字
        MyFirstName: function() {   
           //迭代当前匹配元素集合
            return this.each(function() {   
var obj = $(this);
                //自己的代码  
            });   
        }   
    });   
)(jQuery);
备注1:理解$.fn.extend和$.extend的区别,大概的说前者是将MyFirstName这个方法合并到jquery的实例对象中,例如$(“#txtmy”).add(3,4)这样调用方法,后者是将MyFirstName这个方法合并到jquery的全局对象中,例如$.add(3,4); 这样调用方法
详细区别见(http://ioryioryzhan.iteye.com/blog/232971)

二、有参数的
//创建一个匿名函数   
(function($){   
    //给jQuery附加一个新的方法(详细见备注1)
   $.fn.extend({    
        //插件的名字
        MyFirstName: function() {   
//定义默认参数
Var parms={
Parms1:1,
Parms2:2
}
//合并用户传的参数和默认参数,返回给options(详细见备注2)
var options = $.extend(defaults, options);  
           //迭代当前匹配元素集合
            return this.each(function() { 
//把合并后的参数赋值给o
var o=  options;
//迭代当前匹配元素
var obj = $(this);
                //自己的代码  
            });   
        }   
    });   
)(jQuery);
备注2:var options = $.extend(defaults, options); 意思是把defaults和options合并,如果后者有和前者名称一样的元素,后者覆盖前者,然后合并给defaults,然后defaults赋值给options,如果是var options = $.extend({},defaults, options);那么是把前者和后者合并给{}这个参数,然后赋值给options,defaluts的结构和值都没有变化
详细区别见(http://www.cnblogs.com/holygis/archive/2011/11/02/2232659.html)

[转载]降低即时搜索的服务器压力

mikel阅读(1002)

[转载]降低即时搜索的服务器压力 – 我有我在 – 博客园.

在做即时搜索(就是像百度搜索输入文本框内容的时候自动搜索出类似的信息)的时候一般都是点击键盘触发搜索事件 一般用onkeydowm或onkeyup (也许onpropertychange是很好的,但可惜在ff和chorme下是不支持的)这样每次点击键盘就会搜索 如果有很多用户的情况下,那么服务器的压力是很大的 怎么办 只能减少提交搜索次数解决了下面这两个方法是文本框每次onkeyup的触发事件—Str是搜索关键字
AjaxSearch: function (Str) {
if (Str.trim() == “”) { return false; }
if (NetHome.PostMessage.posting == false) {     //NetHome.PostMessage.posting 一个判断是否在提交中的变量
NetHome.PostMessage.posting = true;
setTimeout(“NetHome.Utility.AjaxSearching()”, 1000);
}
},
AjaxSearching: function () {
var Str = $(‘#searchtxt’).val().trim();//文本框的值
$.post(“/Ajax/AjaxSearch”, { SearchKey: Str }, function (Msg) {
//处理展示搜索内容的代码
}
NetHome.PostMessage.posting = false;
});
},

这样的效果就是 第一次触发提交事件的一秒后才执行提交搜索 搜索的关键字也是一秒后输入的关键字 并且在一次提交过程中,不会再接受其他提交事件  从而大大降低每次点击键盘都提交给服务器带来的压力

注意:setTimeout的第一个参数(待执行的代码)要当作字符串输入 并且代执行的代码
如果是有参数的方法  那么参数必须是全局变量(至少不能是在这个方法中定义的变量)

示例页面

[转载]浅谈SQL SERVER中事务的ACID

mikel阅读(1028)

[转载]浅谈SQL SERVER中事务的ACID – CareySon – 博客园.

简介

ACID,是指在可靠数据库管理系统(DBMS)中,事务(transaction)所应该具有的四个特性:原子性(Atomicity)、一致性 (Consistency)、隔离性(Isolation)、持久性(Durability).这是可靠数据库所应具备的几个特性.下面针对这几个特性进 行逐个讲解.

理解原子性(Atomicity)

原子性意味着数据库中的事务执行是作为原子。即不可再分,整个语句要么执行,要么不执行。

SQL SERVER中,每一个单独的语句都可以看作是默认包含在一个事务之中:

1

所以,每一个语句本身具有原子性,要么全部执行,这么全部不执行,不会有中间状态:

2

上面说了,每一条T-SQL语句都可以看作是默认被包裹在一个事务之中的,SQL Server对于每一条单独的语句都实现了原子性,但这种原子粒度是非常小的,如果用户想要自己定义原子的大小,则需要包含在事务中来构成用户自定义的原子粒度:

3

对于用户来说,要用事务实现的自定义原子性往往是和业务相关的,比如银行转账,从A账户减去100,在B账户增加100,如果这两个语句不能保证原子性的 话,比如从A账户减去100后,服务器断电,而在B账户中却没有增加100.虽然这种情况会让银行很开心,但作为开发人员的你可不希望这种结果.而默认事 务中,即使出错了也不会整个事务进行回滚。而是失败的语句抛出异常,而正确的语句成功执行。这样会破坏原子性。所以SQL SERVER给予了一些选项来保证事务的原子性.

SQL SERVER提供了两大类方式来保证自定义事务的原子性:

1.通过SET XACT_ABORT ON来设置事务必须符合原子性

利用设置XACT_ABORT选项设置为ON,来设置所有事务都作为一个原子处理.下面例子利用两个语句插入到数据库,可以看到开启SET XACT_ABORT ON选项后,事务具有了原子性:

4

2.按照用户设置进行回滚(ROLLBACK)

这种方式具有更高的灵活性,开发人员可以自定义在什么情况进行ROLLBACK,利用TRY CATCH语句和@@ERROR进行判断都属于这种方式.

5

理解一致性(Consistency)

一致性,即在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。

一致性分为两个层面

1.数据库机制层面

数据库层面的一致性是,在一个事务执行之前和之后,数据会符合你设置的约束(唯一约束,外键约束,Check约束等)和触发器设置.这一点是由SQL SERVER进行保证的.

2.业务层面

对于业务层面来说,一致性是保持业务的一致性.这个业务一致性需要由开发人员进行保证.很多业务方面的一致性可以通过转移到数据库机制层面进行保证.比如,产品只有两个型号,则可以转移到使用CHECK约束使某一列必须只能存这两个型号.

理解隔离性(Isolation)

隔离性。事务的执行是互不干扰的,一个事务不可能看到其他事务运行时,中间某一时刻的数据。

在Windows中,如果多个进程对同一个文件进行修改是不允许的,Windows通过这种方式来保证不同进程的隔离性:

Lock

而SQL Server中,通过SQL SERVER对数据库文件进行管理,从而可以让多个进程可以同时访问数据库:

6

SQL Server利用加锁和阻塞来保证事务之间不同等级的隔离性.

一般情况下,完全的隔离性是不现实的,完全的隔离性要求数据库同一时间只执行一条事务,这样的性能可想而知.想要理解SQL Server中对于隔离性的保障,首先要了解事务之间是如何干扰的.

事务之间的互相影响的情况分为几种,分别为:脏读(Dirty Read),不可重复读,幻读

脏读

脏读意味着一个事务读取了另一个事务未提交的数据,而这个数据是有可能回滚的:

7

下面来看一个例子:

两个事务,事务A插入一条数据,但未提交,事务B在此期间进行了读取,读取到了事务A未提交的数据,造成脏读

8

不可重复读(Unrepeatable Read)

不可重复读意味着,在数据库访问中,一个事务范围内两个相同的查询却返回了不同数据。这是由于查询时系统中其他事务修改的提交而引起的。

9

下面来看一个不可重复读的例子:

事务B中对某个查询执行两次,当第一次执行完时,事务A对其数据进行了修改。事务B中再次查询时,数据发生了改变:

10

11

幻读(phantom read)

幻读,是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这 个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样.

13

下面来看一个例子:

事务B更新表中所有的数据,在此期间事务A插入了一条数据,事务B再次查询后,发现居然还有没有修改的数据,产生幻读:

12

理解SQL SERVER中的隔离级别

为 了避免上述几种事务之间的影响,SQL Server通过设置不同的隔离等级来进行不同程度的避免。因为高的隔离等级意味着更多的锁,从而牺牲性能.所以这个选项开放给了用户根据具体的需求进行 设置。不过默认的隔离等级Read Commited符合了99%的实际需求.

SQL Server隔离事务之间的影响是通过锁来实现的,这个概念比较繁杂,所以本文不会详细对这个概念进行讲解.通过阻塞来阻止上述效果

SQL Server提供了5种选项来避免不同级别的事务之间的影响

隔离等级由低到高分别为

Read Uncommited(最高的性能,但可能出现脏读,不可重复读,幻读)

Read commited(可能出现不可重复读,幻读)

Repeatable Read(可能出现幻读)

Serializable(最低的性能,一次只能执行一个事务,但避免了上述所有情况)

SNOPSHOT(这个是通过在tempDB中创建一个额外的副本来避免脏读,不可重复读,会给tempDB造成额外负担,因为不是标准ANSI SQL标准,不详细讨论)

总之,不同的隔离级别是通过加不同的锁,造成阻塞来实现的,来看一个例子:

SQL SERVER通过阻塞来阻止脏读,所以保持独立性会以付出性能作为代价:

14

理解持久性(Durability)

持久性,意味着在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。

即使出现了任何事故比如断电等,事务一旦提交,则持久化保存在数据库中.

SQL SERVER通过write-ahead transaction log来保证持久性。write-ahead transaction log的意思是,事务中对数据库的改变在写入到数据库之前,首先写入到事务日志中。而事务日志是按照顺序排号的(LSN)。当数据库崩溃或者服务器断点 时,重启动SQL SERVER,SQL SERVER首先会检查日志顺序号,将本应对数据库做更改而未做的部分持久化到数据库,从而保证了持久性.

总结

本文简单讲述了ACID的概念和ACID在SQL SERVER中的实现.ACID只是一个理念,并不是某项具体的技术.对于健壮数据库来说,保证ACID是可靠数据库的前提.

[转载]真心好用的VS扩展--NuGet

mikel阅读(896)

转载真心好用的VS扩展–NuGet – 黄云坤 – 博客园.

无聊中手机上网翻到的,先没明白这是什么东西,等我实际体验了一把以后完全震惊了,太给力了!

NuGet的官方说明是:NuGet是一款Visual Studio的扩展,它可以简单的安装、升级开源库和工具。

官网地址:http://www.nuget.org/

官网最醒目的位置就是下载链接,安装完成后我们来快速体验一把。

手上有个小项目需要使用到json格式,一般情况我会先Google一下有没有相关的开源库(这个肯定是有的)。

然后从一些博文中发现了Json.net,然后继续Google之,找到Json.net的官网,然后下载最新的稳定版本,找出DLL文件引用它。

是不是很复杂?很繁琐?(其实没用NuGet之前我一直觉得这样干很方便的)

使用NuGet我们就可以很快搞定了。

右键Managet NuGet Packages

nuget1

搜索json,然后看看结果和右侧的介绍,Json.net排在第一位,点Install安装。

nuget2

然后等待下载完成,可以看到引用里面已经有了Json.net了。

nuget3

那么NuGet到底干了什么呢?下载的开源库在何处呢?看一下输出结果就知道了。

nuget4

在packages文件夹下可以找到相关dll文件。

nuget5

还有命令行模式可以选用

还是以Json.net举例,输入Install-Package Newtonsoft.Json即可。

nuget7

NuGet还有一个优势就是可以处理依赖(我个人觉得Net的依赖复杂程度没有java麻烦)。以Spring.Core为例子,它依赖Common.Logging。

自然NuGet完美解决了。

nuget9

我没有试升级库功能,但是个人感觉NuGet还是有一些局限的。

首先需要联网,其次是每次都下载新的,而且会把针对不同.Net版本的都down下来。